【问题标题】:Specify common resources in a multi-module maven project在多模块maven项目中指定公共资源
【发布时间】:2024-01-15 08:14:02
【问题描述】:

有没有办法在 Maven 中的父项目的模块之间共享资源?例如,我想为一个多模块 Maven 项目中的所有模块指定一个 log4j.properties 文件。

一般情况下,我使用Eclipse IDE通过选择通用项目来创建父项目,然后通过指定pom的封装将其转换为Maven项目。这将创建一个没有 src 等文件夹的“干净”项目结构。我想知道在这种情况下应该将这样的共享资源放在哪里。

EDIT1:我想把公共资源放在父项目中。

【问题讨论】:

    标签: java maven maven-2 maven-3 multi-module


    【解决方案1】:

    另一种方式,放入你的项目根pom:

        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-assembly-plugin</artifactId>
                <!-- don't propagate to child poms -->
                <!-- this will only execute in root pom -->
                <inherited>false</inherited>
                <configuration>
                    <descriptors>
                        <descriptor>assembly.xml</descriptor>
                    </descriptors>
                    <!-- don't add classifier -->
                    <appendAssemblyId>false</appendAssemblyId>
                </configuration>
                <executions>
                    <execution>
                        <phase>initialize</phase>
                        <goals>
                            <goal>single</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
        <plugins>
    

    还有 assembly.xml 的例子

    <assembly xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.2"
              xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
              xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.2 http://maven.apache.org/xsd/assembly-1.1.2.xsd">
    
        <id>resources</id>
    
        <formats>
            <format>jar</format>
        </formats>
    
        <includeBaseDirectory>false</includeBaseDirectory>
    
        <fileSets>
            <fileSet>
                <directory>${project.basedir}/resources/</directory>
                <outputDirectory/>
                <useDefaultExcludes>true</useDefaultExcludes>
                <includes>
                    <include>**</include>
                </includes>
            </fileSet>
        </fileSets>
    </assembly>
    

    Assembly 插件将生成工件并将其附加到当前反应器,因此它将被安装和部署。

    不,您可以在同一个 pom 中将其用作标准依赖事件。

    重要的是在另一个将使用生成的工件的插件之前触发组装(适当的阶段)。

    例如。你可以在你的根 pom 中,下面的配置将传播到你的所有模块:

                  <plugin>
                    <artifactId>some-maven-plugin</artifactId>
                    <executions>
                        <execution>
                            <phase>verify</phase>
                            <goals>
                                <goal>goal</goal>
                            </goals>
                        </execution>
                    </executions>
                    <dependencies>
                        <dependency>
                            <groupId>your.project.groupid</groupId>
                            <artifactI>your.project.artifactId</artifactId>
                            <version>${project.version}</version>
                        </dependency>
                    </dependencies>
                </plugin>
    

    你可以在项目中看到这个方法: https://github.com/s4u/pgp-keys-map resources 目录被所有模块共享。

    【讨论】:

      【解决方案2】:

      我认为您可以将资源和/或 testResources 元素添加到您的 pom.xml 中。 例如。访问额外的测试资源目录添加:

          <testResources>
              <testResource>
                  <directory>src/test/resources</directory>
              </testResource>
              <testResource>
                  <directory>../global/src/test/resources</directory>
              </testResource>
          </testResources>
      

      Maven - Override test resource folder

      【讨论】:

        【解决方案3】:

        是的,这似乎是一个可能的解决方案。但我对它是否感兴趣 可以在父项目中指定这些资源(无需 引入附加模块),因为父项目指定了所有 子级的公共依赖项和 Maven 配置 modules,我认为父项目是最合适的地方 也用于公共资源。

        如果是打包类型 pom ,当指定目标 package 来管理您的共享资源时,只需将 next(检查文件夹)添加到 build pom文件部分:

                <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-resources-plugin</artifactId>
               <executions>
                   <execution>
                       <id>copy-config-files</id>
                       <phase>package</phase>
                       <goals>
                           <goal>copy-resources</goal>
                       </goals>
                       <configuration>
                           <outputDirectory>${project.build.directory}/logconfig</outputDirectory>
                           <resources>
                               <resource>
                                <filtering>false</filtering>
                                <directory>${project.basedir}/src/main/resources</directory>
                               </resource>
                           </resources>
                       </configuration>
                </execution>
               </executions>
            </plugin>
        

        【讨论】:

          【解决方案4】:

          我设法让它像这样工作:

          我创建了一个 project/assembly/test/resources/META-INF/persistence.xml 文件,并将其添加到我的 pom.xml:

          <plugin>
              <groupId>org.apache.maven.plugins</groupId>
              <artifactId>maven-resources-plugin</artifactId>
              <executions>
                  <execution>
                      <id>copy-test-persistence-xml-resources</id>
                      <phase>process-test-sources</phase>
                      <goals>
                          <goal>copy-resources</goal>
                      </goals>
                      <configuration>
                          <outputDirectory>src/</outputDirectory>
                          <resources>
                              <resource>
                                  <directory>${project.parent.basedir}/assembly/</directory>
                                  <filtering>true</filtering>
                              </resource>
                          </resources>
                      </configuration>
                  </execution>
              </executions>
          </plugin>

          【讨论】:

          • 这是行不通的,而且是非常糟糕的做法。
          【解决方案5】:

          另一种可能性是使用远程资源包。您将能够在父项目中对其进行配置。在这个例子中,我想复制一些文件只是为了测试。如果您使用它,您将需要在另一个项目中创建捆绑包。

              <plugin>      
                  <groupId>org.apache.maven.plugins</groupId>         
                  <artifactId>maven-remote-resources-plugin</artifactId>
                  <version>1.5</version>
                  <configuration>
                      <resourceBundles>
                          <resourceBundle>es.sca:myBundle:1.0.0</resourceBundle>
                      </resourceBundles>
                      <attachToMain>false</attachToMain>
                      <attachToTest>true</attachToTest>
                      <appendedResourcesDirectory>${basedir}/src/test/resources</appendedResourcesDirectory>
                  </configuration>            
                  <executions>
                      <execution>
                          <goals>
                              <goal>process</goal>
                          </goals>
                      </execution>
                  </executions>                   
              </plugin>                 
          

          【讨论】:

          • 能否分享一下“如何访问共享资源”的代码sn-p?
          【解决方案6】:

          我将创建一个额外的“基础”模块(项目),打包“jar”,其中包含src/main/resources 中的公共资源。然后我会让其他模块依赖于那个项目。现在他们可以看到类路径上的公共资源。

          【讨论】:

          • 是的,这似乎是一个可能的解决方案。但是我很感兴趣是否可以在父项目中指定这些资源(不引入额外的模块),因为父项目为子模块指定了所有常见的依赖项和Maven配置,我认为父项目是最合适的地方也适用于公共资源。
          • 带有“pom”打包的父项目没有任何资源,它只是一个构建文件,可以作为工件安装/部署。
          • 我明白了。所以用 Maven 父项目来做这件事是不可能的吗? +1,但如果有任何其他建议,我将把问题留待一段时间。
          • 是的,它不会那样工作,或者至少,它会打破惯例。将依赖管理、属性、存储库和所有这些东西添加到父 pom 但文件中,在编译、测试或稍后在运行时需要位于类路径上的文件确实应该放入 jars 中。
          • @AndreasDolk 正如你在回答中所说,如何使其他模块依赖于基本模块,我正在尝试,但它说不能将模块添加到未打包为 pom 的项目中