【问题标题】:How to include a config file in the "META-INF/services" folder of a JAR using Maven如何使用 Maven 在 JAR 的“META-INF/services”文件夹中包含配置文件
【发布时间】:2013-07-06 01:54:55
【问题描述】:

我正在 Eclipse 中开发一个使用 Maven 构建的 Java 项目。我正在使用来自旧项目的一些回收代码,其中一个类在 JAR 的 META-INF/services 文件夹中查找具有特定名称的文件,然后解析该文件的文本。在这个特定的示例中,它会查找具有 Java 接口名称的文件,然后从文件中获取实现的类名称。

所以基本上我要做的是在 JAR 的“META-INF/services”文件夹中包含一个文件,文件名 (X) 和一行文本 (Y)强>。我猜这应该使用 Maven 来完成,也许是通过在 POM 文件中指定一个属性,但我的研究没有发现任何东西。我知道您不应该硬编码或手动输入任何 META 文件,所以我不知道该怎么做。

【问题讨论】:

  • 8 年后,让一个 Maven 项目识别 META-INF/services 文件夹仍然非常困难。如果可能的话。

标签: java eclipse maven pom.xml


【解决方案1】:

Create a new source folder 的位置为 src/main/resources,然后在其中创建您的 META-INF/services 文件夹并放入您的完全限定类名 (FQCN) 文件。这应该会自动将它们复制到 jar 文件中。因此,对于 FQCN 为 com.acme.MyInterface 的接口的实现,您将拥有:

Project
| src
| | main
|   | java
|     | [your source code]
|   | resources
|     | META-INF
|       | services
|         | com.acme.MyInterface

注意com.acme.MyInterface 是文件名,而不是像Java 包那样的目录结构。该文件的名称是您正在实现的接口的 FQCN,在其中,您将在其自己的行上拥有每个实现的 FQCN,例如:

com.example.MyInterfaceImpl
com.example.AnotherMyInterfaceImpl

值得注意的是,这也适用于具有默认源集的 Gradle 项目。

完成此操作后,您可以使用ServiceLoader 加载接口的所有实现:

ServiceLoader<MyInterface> loader = ServiceLoader.load(MyInterface.class);
for (MyInterface service : loader) {
    // Prints com.example.MyInterfaceImpl and com.example.AnotherMyInterfaceImpl
    System.out.println(service.class.getName());
}

注意事项:

  • 所有实现都必须有一个无参数构造函数
  • 使用模块或自定义类加载器的应用程序可能必须使用 ServiceLoader.load 的重载

如果这些条件不适合您,那么您可能需要切换到另一个系统,例如一个 CDI 风格的框架,如 Spring、EJB 等。

【讨论】:

  • 在 services 文件夹中放什么?
  • @OzanKurt 请看一下ServiceLoader类的Javadoc:docs.oracle.com/javase/8/docs/api/java/util/ServiceLoader.html
  • @OzanKurt Here's the related Java trail。简而言之, META-INF/services 中的文件名类似于 META-INF/services/com.acme.MyInterface ,它将包含应用程序中实现的每个 FQCN,每个都在一个新行上,例如com.example.MyInterfaceImpl
  • 谢谢@Brian!这对我帮助很大!
  • META-INF/services/com.acme.MyInterface 还是 META-INF/services/com/acme/MyInterface?
【解决方案2】:

默认情况下,Maven 在以下位置查找资源:

src/main/resources

所以把它放在

src/main/resources/META-INF/services

【讨论】:

  • 在 services 文件夹中放什么?
【解决方案3】:

或者,如果您的项目不使用标准目录结构(或者您只是希望有备用资源目录),您可以手动指定 resource directories POM 文件。

例如,如果您的META-INF/services 位于项目目录根目录下名为resources 的文件夹中,则可以如下指定:

<project>
...
  <build>
    ...
    <resources>
      <resource>
        <directory>resources</directory>
      </resource>
    </resources>
    ...
  </build>
  ...
</project>

您可以通过添加多个&lt;resource&gt; 元素来使用它来指定多个目录。

【讨论】:

  • 在 services 文件夹中放什么?
  • @OzanKurt 我不确定其中的所有内容,但通常存在于 META-INF/services 中的文件的一个示例是自定义 CharsetProvider。
  • 我收到了,需要添加注释。谢谢
猜你喜欢
  • 2016-12-14
  • 2010-11-20
  • 1970-01-01
  • 2017-06-22
  • 1970-01-01
  • 2021-11-24
  • 2012-05-06
  • 2015-12-29
  • 2011-09-16
相关资源
最近更新 更多