17

I need to have a JAR dependency in the Maven generated WAR's WEB-INF/lib folder as x-1.0.final.jar instead of x-1.0.jar, which is the name it has in the repository. What would be the best way to achieve this?

In my POM I have:

<dependency>
  <groupId>foo</groupId>
  <artifactId>x</artifactId>
  <version>1.0</version>
</dependency>

I want this to appear in the WEB-INF/lib folder as x-1.0.final.jar.

It's and external dependency on Maven Central I don't have control over. Also I don't want to force everyone using this to redeploy the dependency to their local repositories.

Is there a Maven plugin that I could utilize or should I start coding my own?

hleinone
  • 4,470
  • 4
  • 35
  • 49
  • How are you going to get them to find the library if you cannot put it online and don't want them to put it locally? – gigadot Feb 11 '11 at 14:08
  • It is an external third-party dependency. And it is online at Maven Central. The name of the JAR is the one that doesn't apply my usage. I want to rename what goes into the `WEB-INF/lib` directory. – hleinone Feb 11 '11 at 14:11
  • I don't think such a solution exist for renaming what goes in to the folder. – gigadot Feb 11 '11 at 14:16
  • You could try to write your own maven plugin to do that. – gigadot Feb 11 '11 at 14:17
  • Well, I think so too unless there'd be one doing this already. – hleinone Feb 11 '11 at 14:21
  • To summarise, you want maven to get `x-1.0.jar` from central repo and rename it before it goes into `WEB-INF/lib`. Are you planning to add your own `x-1.0.jar`? That can cause serious problem when your servlet container try to load the classes, if two jars has the same class names and packages. I am not sure that I understand you correctly. If you are planning to add you own ``x-1.0.jar`, why don't you just make it available online in a private repository under different classifier. – gigadot Feb 11 '11 at 14:30
  • Well, it's all about the Google plugin for Eclipse that I use to run my Google App Engine applications inside the IDE. It expects that in the `WEB-INF/lib` folder there's a JAR named `datanucleus-appengine-1.0.8.final.jar` otherwise it'll add it. Lately the Google App Engine dependencies have been made available in Maven Central, but the `datanucleus-appengine` has version `1.0.8`. So, I'll end up the same library twice which causes classpath errors as you mentioned. To tackle this I thought I could rename the dependency that goes to `WEB-INF/lib`. Hope this clears out my intentions. – hleinone Feb 11 '11 at 14:39
  • 1
    http://maven.apache.org/plugins/maven-war-plugin/examples/skinny-wars.html I have not used it myself but it seems to beable to exclude jar from war. – gigadot Feb 11 '11 at 15:07
  • That should do the trick, but it seems inconsistent. Sometimes the file is there but running `mvn eclipse:eclipse` again removes it. – hleinone Feb 23 '11 at 08:47
  • Note that unless you have a very good reason for needing it to be something very specific, you do not have to change the name in the lib folder. I found it not to be worth the trouble. – Thorbjørn Ravn Andersen May 24 '12 at 11:47
  • It makes sense to want to change a library's name. We're now in the realm of open source, we include many artifacts developed by uncoordinated teams. What if you get to include both com.foo:utils:1.0 and org.bar.filesystem:utils:2.3? You'll get two utils-x.y.jar which looks confusing. – Alessio Stalla Jul 26 '16 at 09:41

4 Answers4

35

You can use maven-dependency-plugin to include artifact under the name that you need.

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-dependency-plugin</artifactId>
    <executions>
      <execution>
        <goals>
          <goal>copy</goal>
        </goals>
        <configuration>
          <artifactItems>
            <artifactItem>
              <groupId>foo</groupId>
              <artifactId>x</artifactId>
              <version>1.0</version>
              <type>jar</type>
              <outputDirectory>${project.build.directory}/${project.build.finalName}/WEB-INF/lib</outputDirectory>
              <destFileName>x-1.0.final.jar</destFileName>
            </artifactItem>
          </artifactItems>
        </configuration>
      </execution>
    </executions>
</plugin>

By default, maven-dependency-plugin is bound to the process-sources phase that seems just enough for your task. Remember to set the scope provided for the artifact in dependencies so that it is not automatically included by the war plugin.

ᄂ ᄀ
  • 5,669
  • 6
  • 43
  • 57
  • 4
    This solution exclude all dependencies of renamed library – Kaltresian Jan 02 '14 at 19:28
  • 2
    be careful destFileName must be in artifactItem elements, mine was outside and it did not work. when I copied into under artifactItem tag problem disappeared – Mustafa Güven Mar 06 '14 at 09:42
  • 1
    This is a good start. If you leav the dependency to be renamed as a regular dependency, you will get all the transitive dependencies included. Then edit in the war plugin to exclude the x.jar. Gives you the best of both worlds. – Jon Jun 26 '14 at 19:04
5

You may want to see if the outputFileNameMapping parameter of maven war plugin can help you.

Raghuram
  • 51,854
  • 11
  • 110
  • 122
3

I know that I'm replying to an old thread, but I needed to perform the above and found this thread helpful. The way I found to achieve this was to perform a 2 step process:

  1. Use the maven-war-plugin to exclude the original jar file from the deliverable.
  2. Use the maven-dependency-plugin to copy the original jar file to the new-named jar file and place this in the WEB-INF/lib directory.

So, by way of illustration, this is how to specify the file you wish to exclude. In this case x-1.0.jar :

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-war-plugin</artifactId>
    <version>2.6</version>
    <configuration>
        <!-- Exclude file: x-1.0.jar from packaging -->
        <packagingExcludes>WEB-INF/lib/x-1.0.jar</packagingExcludes>
    </configuration>
</plugin>

Also specify that a copy must be performed of the file to the new name (x-1.0.final.jar) but this needs to run BEFORE packaging occurs. This is specified by the phase: 'prepare-package':

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-dependency-plugin</artifactId>
    <executions>
        <execution>
            <phase>prepare-package</phase>
            <goals>
                <goal>copy</goal>
            </goals>
            <configuration>
                <artifactItems>
                    <artifactItem>
                        <groupId>the group of the x jar</groupId>
                        <artifactId>x</artifactId>
                        <type>jar</type>
                        <outputDirectory>${project.build.directory}/${project.build.finalName}/WEB-INF/lib</outputDirectory>
                        <destFileName>x-1.0.final.jar</destFileName>
                    </artifactItem>
                </artifactItems>
            </configuration>
        </execution>
    </executions>
</plugin>

In my example I wasn't hard-coding 1.0 but I think this should work for the original posters question.

Phil
  • 1,897
  • 4
  • 25
  • 48
1

Sorry I dont understand your question fully what is the code you have for importing this jar in the POM?

If the Jar you wish to import is called that in the repository and you are importing the correct file in your POM then you shouldn't have to worry about naming conventions of the JAR file.

What i believe you may have to do is rename the file in the repository you can do this simply by going into the Repository Users/.m2 in a explorer window and tracking down the file and renaming it, note this may have implications on other projects.

What i suggest you do is copy the file rename it and add it to the repository with the new artifact id x-1.0.final.jar

mvn install:install-file -Dfile=<path-to-file> -DgroupId=<group-id> \
-DartifactId=<artifact-id> -Dversion=<version> -Dpackaging=<packaging>

fill in the <>

Hope this helps Chris

Chris
  • 865
  • 4
  • 15
  • 25
  • The repository has one name for the JAR, which is different from what I need to have on my WAR. I don't have control over the remote repository and don't want to force everyone using this to redeploy the dependency into their local repositories. – hleinone Feb 11 '11 at 13:55