java 让 Maven2 将资源复制到构建目录,但不要将它们捆绑在 JAR 中

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/4018394/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-30 04:24:32  来源:igfitidea点击:

Having Maven2 copy resources to the build directory, but NOT bundle them in the JAR

javamaven-2netbeans

提问by Steve Perkins

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.

我在 NetBeans 中启动了一个新的 Maven 项目,接受所有默认值。去掉了所有 JAR 依赖项的 POM 被剪切-粘贴在这个问题的底部。

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.

应用程序读取各种属性文件(例如日志记录和配置)。它还读取外部资源,例如字体、图像和声音。我不希望所有这些资源都捆绑到 JAR 文件中。相反,我计划将它们部署在 JAR 部署目录下的子目录中。

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 liketo 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 actuallygetting looks like this:

但是,当我通过 NetBeans(或与此相关的命令行)执行“clean-and-build”或“exec”时……我实际得到的结果如下:

+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 otherway! (i.e. get resources intoa JAR rather than keep them out)

有人可以指出我获得第一个结果而不是第二个结果的正确方向吗?如果这是一个愚蠢的问题(我是 Maven 新手),或者如果我忽略了之前询问的重复问题,我深表歉意。然而,从我对堆栈溢出进行搜索......它看起来像所有重复的问题,尝试走其他路!(即将资源放入JAR 中而不是将它们排除在外

pom.xml:

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>
    ...

回答by Newtopian

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:

尽管提议的解决方案会起作用,但它们基本上是围绕 Maven 约定工作的。更好的选择是过滤掉资源,这样它们就不会包含在 jar 中,但在 IDE 中工作时仍可作为资源使用。在 pom 中它应该是这样的:

<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.

这将有效地将它们从 jar 中排除,而无需任何解决方法。

Hereis the doc page for the jar plugin.

是 jar 插件的文档页面。

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 assemblyplugin. 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.

虽然以上内容将回答您的问题,但我可能会建议一些额外的可能性来帮助您努力。第二步,为了仍然使这些资源可用,您可以使用程序集插件打包您的项目。这将允许您创建一个 zip 文件并将所有文件、资源和 jar 放置在适当的位置,以便在解压缩 zip 时所有内容就位。

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.

如果这个项目是更大工作的一部分,你仍然可以为每个你会遇到这种情况的地方使用组装插件,在主项目中,你可以将它们提取并重新组装在一个更大的 zip 中,包括所有必要的工件。

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.

最后,我建议您保留目标下的目录结构原样。如果您自定义它,最好通过 Maven 变量来完成,以便更改渗透到其他插件中。如果您在 Maven 完成后手动删除和重命名内容,您以后可能会遇到问题。通常 Maven jar 插件应该能够正确地配置它,如果你按照你想要的方式配置它,这样你就不必担心目标下的内容。我个人使用 Eclipse,并且 pusign 非常擅长使 IDE 和 Maven 配置同步。对于 NetBeans,我怀疑情况也会如此。如果不是,最好的方法是在 NetBeans 中配置您的项目,将目标/类用作构建工件的目标文件夹,并将目标/测试类用作从 src/test/java 构建的内容。

回答by Pascal Thivent

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.

如果您坚持使用默认位置 ( src/main/resources),我认为您必须配置一些排除项(见下文)以避免默认情况下复制资源,然后使用与上述相同的方法。

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.

另一种选择是使用 AntRun maven 插件和 Ant 来移动文件,但这并不是真正的 maven 方式,所以我不会详细说明。

Resources

资源

回答by Eugene Kuleshov

You can sonfigure a special execution of resources:copy-resourcesgoal.

你可以定义一个特殊的资源执行:copy-resources目标。

回答by jgifford25

Eugene is on the right track but there's a better way to make this work.

Eugene 走在正确的轨道上,但有更好的方法来完成这项工作。

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.

您将无法删除“classes”目录,但您可以为其指定一个不会干扰 NetBeans 的不同名称。

You can find more about the <outputDirectory>element here.

您可以在此处找到有关该<outputDirectory>元素的更多信息。

You can find more about the jar plugin here.

您可以在此处找到有关 jar 插件的更多信息。

You can find more about the <resource>element here.

您可以在此处找到有关该<resource>元素的更多信息。

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.

作为旁注,您可能需要考虑在 1.6 JDK 下运行 Maven 并派生 maven-compiler-plugin 以使用 1.4 JDK 进行编译。您可以在此处了解更多信息。这应该会增加您的编译时间。您还可以在运行测试用例时告诉 surefire 也使用 1.4 JDK 来执行。