我创建了一个简单的 Java9 服务示例,其中包含一个服务接口(interface)、两个服务实现以及一个使用 ServiceLoader 的驱动程序。我能够使用 module-path 成功执行示例,但是当我尝试使用 java -cp (classpath) 执行相同的示例时,我没有得到任何输出,甚至没有任何错误。
目录结构
out
├── driver
│ ├── com
│ │ └── company
│ │ └── driver
│ │ └── driver.class
│ └── module-info.class
├── firstServiceImpl
│ ├── com
│ │ └── company
│ │ └── first
│ │ └── serviceImpl
│ │ └── FunImpl1.class
│ └── module-info.class
├── secondServiceImpl
│ ├── com
│ │ └── company
│ │ └── second
│ │ └── serviceImpl
│ │ └── FunImpl2.class
│ └── module-info.class
└── serviceInterface
├── com
│ └── company
│ └── service
│ └── Fun.class
└── module-info.class
编译命令
javac -d out --module-source-path src src/driver/driver.java src/firstServiceImpl/FunImpl1.java src/secondServiceImpl/FunImpl2.java src/serviceInterface/Fun.java
上述命令使用模块源路径编译代码。
运行命令
java -cp out/driver:out/serviceInterface/:out/firstServiceImpl/ com.sunil.driver.driver
上述命令使用类路径运行代码。
使用module-source-path编译后并使用classpath运行代码。我没有收到任何错误或输出。 请帮助我理解为什么使用类路径运行时没有输出。
最佳答案
服务提供者的定位方式取决于服务提供者是否位于类路径或模块路径上。 ServiceLoader
的文档对此进行了描述。 :
Deploying service providers as modules
A service provider that is developed in a module must be specified in a provides directive in the module declaration. The provides directive specifies both the service and the service provider; this helps to locate the provider when another module, with a uses directive for the service, obtains a service loader for the service. It is strongly recommended that the module does not export the package containing the service provider. There is no support for a module specifying, in a provides directive, a service provider in another module.
[...]
Deploying service providers on the class path
A service provider that is packaged as a JAR file for the class path is identified by placing a provider-configuration file in the resource directory
META-INF/services
. The name of the provider-configuration file is the fully qualified binary name of the service. The provider-configuration file contains a list of fully qualified binary names of service providers, one per line.[...]
基本上,如果您希望能够加载服务提供程序,无论它是放置在类路径还是模块路径上,您都需要在 模块中指定
文件并在 provides
指令-info.javaMETA-INF/services
下添加适当的提供程序配置文件。您还必须确保使用正确的方法来加载服务提供者:
ServiceLoader#load(Class,ClassLoader)
- 在命名模块(即模块路径)和未命名模块(即类路径)中定位提供程序。
ServiceLoader#load(ModuleLayer,Class)
- 仅在命名模块(即模块路径)中查找提供程序。
关于java - 使用 Java 类路径执行 Java 9+ 服务,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58352202/