Having Maven2 copy resources to the build directory, but NOT bundle them in the JAR
I've started a new Maven project in NetBeans, accepting all the defaults. The POM, with all the JAR dependencies stripped out, is cut-n-pasted at the bottom of this question.
The application reads in various properties files (e.g. logging and config). It also reads in external resources such as fonts, images, and sounds. I do NOT want all these resources to be bundled up into the JAR file. Instead, I plan to deploy them in subdirectories beneath the directory where the JAR is deployed.
A simplified view of the project's directory structure looks like this:
-src
|---main
|---java
|---com.mypackage, etc
|---resources
|---conf
|---fonts
|---images
|---sounds
+target
What I would like to have after a clean build would look like this:
+src
-target
|---myproject-1.0.0.jar (compiled contents of "src/main/java" ONLY)
|---conf
|---fonts
|---images
|---sounds
However, when I do a "clean-and-build" or an "exec" through NetBeans (or the command-line for that matter)... what I'm actually getting looks like this:
+src
-target
|---classes
|---("src/main/java" and "开发者_开发技巧src/main/resources" slammed together)
|---myproject-1.0.0.jar (the "classes" subdirectory JAR'ed up)
Can someone point me in the right direction for getting that first result rather than the second? I apologize if this is a silly question (I'm a Maven rookie), or if I overlooked a previously-asked duplicate. However, from the searching I've done on Stack Overflow... it looks like all the duplicate questions try to go the other way! (i.e. get resources into a JAR rather than keep them out)
pom.xml:
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>steveperkins</groupId>
<artifactId>myproject</artifactId>
<packaging>jar</packaging>
<version>1.0.0</version>
<name>My Project</name>
<url>http://maven.apache.org</url>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>2.0.2</version>
<configuration>
<source>1.4</source>
<target>1.4</target>
</configuration>
</plugin>
</plugins>
</build>
<dependencies>
...
Although the proposed solutions would work they basically work around the maven conventions. A better alternative would be to filter out the resources so they are not included in the jar but still available as resources while working in the IDE. In the pom it should look like this:
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<executions>
<execution>
<goals>
<goal>jar</goal>
</goals>
<configuration>
<excludes>
<exclude>/conf/**</exclude>
<exclude>/fonts/**</exclude>
<exclude>/images/**</exclude>
<exclude>/sounds/**</exclude>
</excludes>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
This would effectively exclude them from the jar without any workarounds.
Here is the doc page for the jar plugin.
Though the above will answer your question may I suggest some additional possibility that could help you in your endeavour. As a second step, to still make these resources available you could package your project using the assembly plugin. this would allow you to create a zip file and place all the files, resources and jar, in an appropriate location so that when the zip is unpacked everything just falls into place.
If this project is part of a larger work you can still use the assembly plugin for each where you would have this situation and in the main project you could extract and reassemble them in a larger zip including all the necessary artifacts.
Lastly I suggest you leave the directory structure under target as-is. If you customize it it would be preferable to do it through the Maven variables so that the changes percolate to the other plugins. If you manually remove and rename stuff once Maven has gone through you may run into problems later. Normally the Maven jar plugin should be able to just get it right if you configure it the way you want so you have no needs to worry about what comes under target. Personally I use Eclipse and the pusign is pretty good at getting the IDE and Maven config in sync. For NetBeans I would suspect this would also be the case. If not the best approach would be to configure your project in NetBeans to use target/classes as a target folder for built artifacts and target/test-classes for stuff built from src/test/java.
Personally, I would not use the default location of resources but an "extra" location and configure the resources plugin to copy them where you want from there:
<project>
...
<build>
<plugins>
<plugin>
<artifactId>maven-resources-plugin</artifactId>
<version>2.4.3</version>
<executions>
<execution>
<id>copy-resources</id>
<!-- here the phase you need -->
<phase>validate</phase>
<goals>
<goal>copy-resources</goal>
</goals>
<configuration>
<outputDirectory>${basedir}/target</outputDirectory>
<resources>
<resource>
<directory>src/non-packaged-resources</directory>
<filtering>true</filtering>
</resource>
</resources>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
...
</build>
...
</project>
If you insist with using the default location (src/main/resources
), I think you'll have to configure some exclusions (see below) to avoid resources getting copied by default and then use the same approach as above.
Another option would be to use the AntRun maven plugin and Ant to move files but this is not really the maven way so I won't detail it.
Resources
- Copy Resources
- Including and excluding files and directories
You can sonfigure a special execution of resources:copy-resources goal.
Eugene is on the right track but there's a better way to make this work.
It should look something like this:
<build>
<outputDirectory>target/${artifactId}-${version}</outputDirectory>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>2.3.1</version>
<configuration>
<classesDirectory>${project.build.outputDirectory}</classesDirectory>
<outputDirector>target</outputDirectory>
</configuration>
</plugin>
</plugins>
<resources>
<resource>
<directory>src/main/resources/conf</directory>
<targetPath>../conf</targetPath>
</resource>
<resource>
<directory>src/main/resources/ANOTHER_PATH</directory>
<targetPath>../ANOTHER_PATH</targetPath>
</resource>
</resources>
</build>
You won't be able to get rid of the 'classes' directory, but you'll be able to give it a different name that shouldn't interfere with NetBeans.
You can find more about the <outputDirectory>
element here.
You can find more about the jar plugin here.
You can find more about the <resource>
element here.
As a side note, you may want to consider running Maven under a 1.6 JDK and fork the maven-compiler-plugin to use your 1.4 JDK for compiling. You can find out more about this here. That should give you a boost to your compile time. You can also tell surefire when running test cases to use the 1.4 JDK for execution as well.
精彩评论