开发者

Maven add jars through systemPath/system but not added to war or anywhere else

I want to add a jar file through the systemPath from the local file-system relative to my project directory structure, not on a remote repository. I added the dependency declaration but maven doesn't do anything else with it.

In the declaration below, I want the jar file copied to my target web-inf/lib directory and also jarred as part of the war file. At present, that doesn't happen. How would I get the jar file copied to my war file?

This is the output from debug maven mode:

DEBUG] cglib:cglib-nodep:jar:2.2:test (setting scope to: compile)^M
DEBUG] Retrieving parent-POM: org.objenesis:objenesis-parent:pom:1.2 for project: null:obje开发者_开发问答nesis:ja
DEBUG]   org.objenesis:objenesis:jar:1.2:test (selected for test)^M
DEBUG]   org.javap.web:testRunWrapper:jar:1.0.0:system (selected for system)^M
DEBUG] Plugin dependencies for:
...


<dependency>
    <groupId>org.javap.web</groupId>
    <artifactId>testRunWrapper</artifactId>
    <version>1.0</version>
    <scope>system</scope>
    <systemPath>${basedir}/lib/testRunWrapper.jar</systemPath>
</dependency>
<plugin>
    <artifactId>maven-war-plugin</artifactId>
    <configuration>                 
        <webResources>
            <resource>
                <directory>WebContent</directory>
            </resource>
        </webResources>
    </configuration>
</plugin>


OK, I did this: Note the directory structure at the bottom. With the approach below, the jar file from the relative project path is treated as a first class citizen like the other jars. The listing below corrects my original problem. With the pom.xml listing below, the jar file is copied to my target directory.

<repositories>
    <repository>
        <id>JBoss</id>
        <name>JBoss Repository</name>
        <layout>default</layout>
        <url>http://repository.jboss.org/maven2</url>
    </repository>

    <repository>
       <id>my-local-repo</id>
       <url>file://${basedir}/lib/repo</url>
    </repository>
</repositories>

<dependency>
    <groupId>testRunWrapper</groupId>
    <artifactId>testRunWrapper</artifactId>
    <version>1.0.0</version>            
</dependency>

$ find repo
repo
repo/testRunWrapper
repo/testRunWrapper/testRunWrapper
repo/testRunWrapper/testRunWrapper/1.0.0
repo/testRunWrapper/testRunWrapper/1.0.0/testRunWrapper-1.0.0.jar


Using the maven dependency plugin does the job:

<build>
    <plugins>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-dependency-plugin</artifactId>
            <version>2.8</version>
            <executions>
                <execution>
                    <id>copy-dependencies</id>
                    <phase>compile</phase>
                    <goals>
                        <goal>copy-dependencies</goal>
                    </goals>
                    <configuration>
                        <outputDirectory>${project.build.directory}/${project.build.finalName}/WEB-INF/lib</outputDirectory>
                        <includeScope>system</includeScope>
                    </configuration>
                </execution>
            </executions>
        </plugin>
    </plugins>
</build>


Don't use system. To do what you want, just declare as a regular (compile) dependency and use mvn install:install-file into your local repository. Everything else will work as you want (lib will be copied, etc.) That will mean that the build will only work on your machine, however.

To properly fix this for your (internal) team, you will want to set up a repository (e.g. Artifactory, Nexus, or Archiva). This is almost a must for team use of Maven.

If this is for public (e.g. open source) use you can either mimic a repository via an http server or put up a real repository.


try something like this (using Ant plugin to manually put the jar to output directory):

<plugin>
       <artifactId>maven-antrun-plugin</artifactId>
       <executions>
         <execution>
           <phase>test</phase>
           <goals>
             <goal>run</goal>
           </goals>
           <configuration>
             <tasks>
               <copy file="${project.basedir}/pathToJAR.jar"
                     todir="${project.build.directory}/outputFileName/WEB-INF/lib"/>
             </tasks>
           </configuration>
         </execution>
       </executions>
     </plugin>


AFAIK, system scoped dependencies are somewhat like those with provided scope and thus are not included in the target artifact. Why don't you install the dependency into your local repository instead?

From the doc:

system
This scope is similar to provided except that you have to provide the JAR which contains it explicitly. The artifact is always available and is not looked up in a repository.


In case this answer didn't work for you as it didn't for me and you know that system is a bad scope, you can try this solution where you are Installing the jar by using install-plugin (scroll down a bit), which installs the JAR into your actual local Maven-repository. Basically you only need to add this plugin to your pom.xml:

<plugin>
  <groupId>org.apache.maven.plugins</groupId>
  <artifactId>maven-install-plugin</artifactId>
  <version>2.4</version>
  <executions>
    <execution>
      <phase>initialize</phase>
      <goals>
        <goal>install-file</goal>
      </goals>
      <configuration>
        <groupId>myGroupId</groupId>
        <artifactId>myArtifactId</artifactId>
        <version>myVersion</version>
        <packaging>jar</packaging>
        <file>${basedir}/lib/xxx.jar</file>
      </configuration>
    </execution>
  </executions>
</plugin>

Fill in the appropriate values for groupId, artifactId and version and put your original jar file into the <project-home>/lib-directory and fix file above. You can add more execution-sections, but then don't forget to add ids there, like:

      <execution>
        <id>common-lib</id>

Everybody who updates from the code-repo needs to call mvn initialize once.

And all Eclipse-enthusiasts may add this to pom.xml, too, to get rid of errors in Eclipse:

<pluginManagement>
  <plugins>
    <!-- This plugin's configuration is used to store Eclipse m2e settings 
      only. It has no influence on the Maven build itself. -->
    <plugin>
      <groupId>org.eclipse.m2e</groupId>
      <artifactId>lifecycle-mapping</artifactId>
      <version>1.0.0</version>
      <configuration>
        <lifecycleMappingMetadata>
          <pluginExecutions>
            <pluginExecution>
              <pluginExecutionFilter>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-install-plugin</artifactId>
                <versionRange>[2.4,)</versionRange>
                <goals>
                  <goal>install-file</goal>
                </goals>
              </pluginExecutionFilter>
              <action>
                <execute></execute>
              </action>
            </pluginExecution>
          </pluginExecutions>
        </lifecycleMappingMetadata>
      </configuration>
    </plugin>
  </plugins>
</pluginManagement>


The problem with using a reference to the file system is that dependent projects will not be able to globally access this jar file. i.e. the dependent project's ${basedir} is different and thus the .jar file won't be found.

Global repositories on the other hand are universally accessible.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜