Building a WAR project with unzipped JAR dependenc

2019-01-26 06:23发布

问题:

I have two projects, my-lib and my-webapp. The first project is a dependency of my-webapp. Thus, when ask Maven2 to build my WAR, the my-lib JAR is added in the WEB-INF/lib/ directory of the web application.

However, I want to have the my-lib JAR unzipped directly in the WEB-INF/classes directory, exactly as if the my-lib sources were contained in the project my-webapp.

In others words, instead of having the following WAR content:

my-webapp/
  ...
  WEB-INF/
    lib/
      my-lib-1.0.jar
      ... (others third libraries)

I want to have that:

my-webapp/
  ...
  WEB-INF/
    classes/
      my-lib files
    lib/
      ... (others third libraries)

Is there a way to configure the my-webapp or the Maven2 war plugin to achieve that?

回答1:

As blaufish's answer says, you can use the maven-dependency-plugin's unpack mojo to unpack an artifact. However to avoid the jar appearing in WEB-INF/lib, you need to not specify it as a dependency, and instead configure the plugin to unpack specific artifacts.

The following configuration will unpack the contents of some.group.id:my-lib:1.0:jar into target/classes during the process-resources phase, even if the artifact is not defined as a dependency. Be careful when doing this though as there is potential to clobber your actual content, this can cause much debugging.

<plugin>
  <groupId>org.apache.maven.plugins</groupId>
  <artifactId>maven-dependency-plugin</artifactId>
  <executions>
    <execution>
      <id>unpack-my-lib</id>
      <phase>process-resources</phase>
      <goals>
        <goal>unpack</goal>
      </goals>
      <configuration>
        <artifactItems>
          <artifactItem>
            <groupId>some.group.id</groupId>
            <artifactId>my-lib</artifactId>
            <version>1.0</version>
            <type>jar</type>
            <overWrite>false</overWrite>
          </artifactItem>
        </artifactItems>
        <outputDirectory>${project.build.outputDirectory}</outputDirectory>
        <overWriteReleases>false</overWriteReleases>
      </configuration>
    </execution>
  </executions>
</plugin>


回答2:

You can configure the maven-dependency-plugin to just do that, unpack instead of copying a jar as explained here.

<project>
[...]
<build>
 <plugins>
   <plugin>
     <groupId>org.apache.maven.plugins</groupId>
     <artifactId>maven-dependency-plugin</artifactId>
     <version>2.5.1</version>
     <executions>
       <execution>
         <id>unpack</id>
         <phase>package</phase>
         <goals>
           <goal>unpack</goal>
         </goals>
         <configuration>
           <artifactItems>
             <artifactItem>
               <groupId>junit</groupId>
               <artifactId>junit</artifactId>
               <version>3.8.1</version>
               <type>jar</type>
               <overWrite>false</overWrite>
               <outputDirectory>${project.build.directory}/alternateLocation</outputDirectory>
               <destFileName>optional-new-name.jar</destFileName>
               <includes>**/*.class,**/*.xml</includes>
               <excludes>**/*test.class</excludes>
             </artifactItem>
           </artifactItems>
           <includes>**/*.java</includes>
           <excludes>**/*.properties</excludes>
                 <outputDirectory>${project.build.directory}/wars</outputDirectory>
           <overWriteReleases>false</overWriteReleases>
           <overWriteSnapshots>true</overWriteSnapshots>
         </configuration>
       </execution>
     </executions>
   </plugin>
 </plugins>
</build>
[...]
</project>


回答3:

The unpack mojo seems to be close to what you are aiming for. Not sure how to complete the entire flow you are proposing though.

(btw, I am doubtful if this a good idea. utility classes should go into jars, and the jars are put either in the WAR or io the EAR. Unpacking utility jars seems wrong)



回答4:

I was able to use the unpack mojo as described above, plus I marked the dependency itself as "provided" (scope) to avoid duplicating the jar contents under WEB-INF/lib.



回答5:

[Oops, just realized that you were using Maven. I don't delete this answer because it may come to the rescue of some Ant user. So there's no need to mod me down...]

How many times to I have to mention that Jar, War and Ear Ant tasks are subtasks of the Zip one? :-) If I remember correctly, something like this would do the trick:

<war dist="my-webapp.war">
    <zipgroupfileset dir="libs" includes="*.jar" prefix="WEB-INF/classes"/>
</war>

Also worth a trial is with src="mylib.jar" but I haven't tested this option.