为啥maven在构建过程中不复制属性文件?

Posted

技术标签:

【中文标题】为啥maven在构建过程中不复制属性文件?【英文标题】:Why does maven not copy the properties files during the build process?为什么maven在构建过程中不复制属性文件? 【发布时间】:2011-07-28 11:30:18 【问题描述】:

我找到的任何东西都无法帮助我解决这一具体案例。我最近从一个普通的旧 java web 应用程序项目(正在运行)切换到一个 maven web 项目。我得到以下运行时异常:

java.util.MissingResourceException: Can't find bundle for base name com.myapp.config, locale en

我正在使用 Netbeans 创建一个 JSF 2.0、Spring 和 Hibernate Web 应用程序。我有以下目录结构:

src\main\java\com\myapp     包含 config.properties src\main\resources               空 target\myapp\WEB-INF\classes\com\myapp     包含已编译的类文件,没有 config.properties src\main\java\com\myapp                               包含 config.properties

对目标文件夹中的 WAR 文件的检查没有显示任何属性文件的迹象,因此就好像 Maven 构建插件没有复制属性文件一样。我知道你可以在 pom 中放置一个标签,但它对我不起作用。下面的链接提到资源文件夹(对我来说是空的)在构建过程中包含其内容,但如果是这种情况,您如何从 Netbeans 执行此操作?我只想将属性文件与我的战争一起打包,以便在部署到服务器时可以访问它。 http://maven.apache.org/plugins/maven-war-plugin/examples/adding-filtering-webresources.html

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>com.myapp</groupId>
<artifactId>myapp</artifactId>
<packaging>war</packaging>
<version>1.0-SNAPSHOT</version>
<name>myapp</name>
<url>http://maven.apache.org</url>
<repositories>
    <repository>
        <id>java.net</id>
        <name>Repository hosting the Java EE 6 artifacts</name>
        <url>http://download.java.net/maven/2</url>
    </repository>
</repositories>
<dependencies>
    <dependency>
        <groupId>javax.faces</groupId>
        <artifactId>jsf-api</artifactId>
        <version>2.1</version>
        <scope>provided</scope>
    </dependency>
    <dependency>
        <groupId>javax</groupId>
        <artifactId>javaee-web-api</artifactId>
        <version>6.0</version>
        <scope>provided</scope>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-hibernate3</artifactId>
        <version>2.0.8</version>
    </dependency>
    <dependency>
        <groupId>com.amazonaws</groupId>
        <artifactId>aws-java-sdk</artifactId>
        <version>1.1.8</version>
    </dependency>
    <dependency>
        <groupId>net.authorize</groupId>
        <artifactId>java-anet-sdk</artifactId>
        <version>1.4.2</version>
    </dependency>
    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
        <version>5.1.15</version>
    </dependency>
    <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
        <version>3.8.2</version>
        <scope>test</scope>
    </dependency>
</dependencies>
<build>
    <plugins>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-compiler-plugin</artifactId>
            <version>2.3.2</version>
            <configuration>
                <source>1.6</source>
                <target>1.6</target>
            </configuration>
        </plugin>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-war-plugin</artifactId>
            <version>2.1.1</version>
            <configuration>
                <failOnMissingWebXml>false</failOnMissingWebXml>
            </configuration>
        </plugin>
    </plugins>
    <finalName>$artifactId</finalName>
</build>
<profiles>
    <profile>
        <id>endorsed</id>
        <activation>
            <property>
                <name>sun.boot.class.path</name>
            </property>
        </activation>
        <build>
            <plugins>
                <plugin>
                    <groupId>org.apache.maven.plugins</groupId>
                    <artifactId>maven-compiler-plugin</artifactId>
                    <configuration>
                        <!-- javaee6 contains upgrades of APIs contained within the JDK itself.
                             As such these need to be placed on the bootclasspath, rather than classpath of the
                             compiler.
                             If you don't make use of these new updated API, you can delete the profile.
                             On non-SUN jdk, you will need to create a similar profile for your jdk, with the similar property as sun.boot.class.path in Sun's JDK.-->
                        <compilerArguments>
                            <bootclasspath>$settings.localRepository/javax/javaee-endorsed-api/6.0/javaee-endorsed-api-6.0.jar$path.separator$sun.boot.class.path</bootclasspath>
                        </compilerArguments>
                    </configuration>
                    <dependencies>
                        <dependency>
                            <groupId>javax</groupId>
                            <artifactId>javaee-endorsed-api</artifactId>
                            <version>6.0</version>
                        </dependency>
                    </dependencies>
                </plugin>
            </plugins>
        </build>
    </profile>
</profiles>
<properties>
    <netbeans.hint.deploy.server>gfv3ee6</netbeans.hint.deploy.server>
</properties>

【问题讨论】:

【参考方案1】:

默认情况下,Maven 不会从 java 源代码树中复制资源,但您可以通过将其添加到您的 pom.xml 中来做到这一点:

<build>
  <resources>
    <resource>
      <directory>src/main/java</directory>
      <excludes><exclude>**/*.java</exclude></excludes>
    </resource>
  </resources>
</build>

确保排除 java 源文件。

来自https://rogerkeays.com/how-to-change-mavens-default-resource-folder

【讨论】:

感谢您的解释:)【参考方案2】:

您的项目在 Netbeans 中配置的构建路径是什么?您可以尝试将其更改为src/main/webapp/WEB-INF/classes。这样,从您的src/main/java 文件夹编译的类文件以及您在src/main/resources 下拥有的任何资源都应该包含在生成的 WAR 中。然后,如果您将 config.properties 文件放在 src/main/resources 文件夹下,您就可以访问它。

您还可以查看 pom.xml 中的任何 includes 部分,并确保您没有意外排除某些内容(如果您明确包含某些内容,您可能会隐含排除其他所有内容)。

【讨论】:

我附上了上面的 pom.xml。类路径标签可能是我需要编辑的。如上所述,我不想将东西放在资源文件夹中,因为如果我将它移到那里,它就不会显示在 netbeans 中。 Netbeans 应该能够处理资源目录中的属性文件。请参阅netbeans.org/community/magazine/html/04/maven.html,大约在它谈论资源的一半(或者只是在页面上搜索资源并阅读它的内容)。 我认为 netbeans 的文章为我指明了正确的方向。 Netbeans 项目选项卡中有一个名为“Other Sources”的文件夹。您需要在相同的所需包结构下将非类文件(如 .properties 文件)添加到“Other Sources”>“src/main/resources”。我知道它必须是简单的!我无法告诉你我花了多少时间在这上面。非常感谢@squawknull!你摇滚。 我遇到了类似的问题,但没有解决。我必须在包名称的开头添加包名称作为 ResourceBundle.getBundle(packageName+"mybundle") 才能工作【参考方案3】:

默认情况下,maven 将包含资源文件夹下的所有文件。如果您的属性文件不在资源文件夹中,那么您需要在 build 部分下的 pom.xml 文件中包含以下内容。

<build>
/* other tags like <plugins> goes here */
<sourceDirectory>src/main/java</sourceDirectory>  
    <resources>
        <resource>
            <directory>src/main/java</directory>
            <includes>
                <include>**/*.xml</include>
            </includes>
        </resource>
    </resources>
/* other tags like <plugins> goes here */
</build>

【讨论】:

【参考方案4】:

尝试将您的 config.properties 放在 src\main\resources\com\myapp 下。我能够在本地项目上对此进行测试。我正在运行 Maven 3.0.2。

使用 webapp 原型创建了一个 mvn 示例项目:

mvn archetype:generate -DgroupId=com.mycompany.app -DartifactId=my-webapp -DarchetypeArtifactId=maven-archetype-webapp

在 src/main/resources/com/foo 创建一个目录,并在其下放置一个 foo.properties 文件。

运行构建:

mvn clean install

然后,当查看生成的目标目录时,会出现 foo.properties 文件:

ls -al target/my-webapp/WEB-INF/classes/com/foo/
-rw-r--r--  1 sblaes  staff    4 Apr  2 22:09 foo.properties

您可以在您的机器上尝试这些步骤。如果可行,那么开始尝试通过从中删除一些东西来简化上面的 POM,看看它是否开始工作。反复试验并不好玩,但我只是看不出有什么东西会破坏它。

【讨论】:

我试过了,仍然给出了同样的异常。有趣的是 src\main\webapp 是被复制到目标目录以进行就地部署的内容。 webapp 文件夹仅包含 facelet 页面和 web-inf 下的 xml 配置文件。没有属性文件。即使将 config.properties 复制到资源文件夹确实有效,我也无法在 Netbeans 项目中查看它。还有其他想法吗? Hrmm,我刚刚在本地尝试过,并且属性文件被复制了...您可以将 pom.xml 的内容添加到上面的问题中吗?您可以尝试使用“mvn clean install”在 Netbeans 之外运行构建,看看它是否显示在创建的 war 文件内的 WEB-INF 目录中? 我在命令行中手动运行它,它产生的结果与我在 IDE 中时相同。构建总是成功的。只是当视图中的 EL 尝试解析 #config['propertyKey'] 并抛出 MissingResourceException 时。战争没有任何配置文件。奇怪的是,切换到maven的时候,会出现这个问题,但是作为一个普通的java web项目却没有。我切换到 maven 以避免依赖噩梦。 嗯,我看不出你的 POM 有什么问题。我无法想象那些其他描述符会破坏这一点……您可以尝试稍微简化 POM 以查看是否有其他原因导致错误或以非预期的方式影响构建过程。我将在上面的示例项目中粘贴一些信息。

以上是关于为啥maven在构建过程中不复制属性文件?的主要内容,如果未能解决你的问题,请参考以下文章

为啥百分号 (%) 在 crontab 中不起作用? [复制]

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

在 Maven 构建期间将文件夹从源复制到目标

为啥复制功能在 setTimeout 中不起作用?

为啥 strcpy 在 C 中不安全? [复制]

为啥默认约束在mysql中不起作用? [复制]