问题标签 [serviceloader]
For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.
java - Java:无法获得正常工作的 ServiceLoader
我对 Java很陌生(来自 C# .NET 背景)。尝试通过结合使用 Google Guice 和 ServiceLoader 创建“扩展/IoC”样式架构,但似乎无法让 ServiceLoader 部分运行 Java 1.7.0_75 和 IntelliJ IDEA 14。
我的项目中有一个模块,它实际上是一个名为 ViProJ.Bcl 的基类库,其中包含一个名为 com.vipro.bcl.SimplePluginLoader 的接口。
我有另一个名为 ViProJ.TestModules 的模块,它包含一个名为 com.vipro.test.TestModule1 的 SimpleModuleLoader 实现。
在我的 src 文件夹中有一个资源文件夹(在模块设置屏幕中标记为资源),其中包含一个名为 META-INF.services 的文件夹,其中包含一个名为 com.vipro.bcl.SimpleModuleLoader 的文件。此文件中的值为 com.vipro.test.TestModule1。
我有两个由 IntelliJ 创建的工件(在同一目录中),第一个是一个具有从命令行运行的 Main 函数的模块。它像这样加载服务加载器:
另一个是前面提到的测试库。当我对此进行调试时,服务加载器不包含任何类,因此类的导出不起作用。
当我在 7zip 中打开 jar 文件时,我可以看到 META-INF\services\com.vipro.bcl.SimpleModuleLoader 因此 IntelliJ 已正确打包这些文件。
MANIFEST.MF 文件如下所示:
不太确定为什么清单是在谈论 Guice 而不是我的模块?可能不会导致此失败?谁能告诉我为什么这不起作用?我确定我没有给你你需要的一切,但不确定我还应该在这里包括什么?
这些模块Module
使用 .impl 文件而不是 pom.xml (Maven) 进行构建,如下所示:
我的注入代码使用 MultiBinder,如下所示:
android - ServiceLoader.load 没有找到 META-INF/services
所以我想构建一个可扩展的 android 应用程序,开发人员可以在其中添加“CustomDevice”类,主程序将自动运行它们而无需编辑现有代码。
我已经阅读了有关服务提供者接口的信息,并认为这将是一个很好的解决方法。
所以我对其进行了测试并创建了一个名为“ICustomDevice”的接口,自定义设备类有望实现。
我创建了一个名为“DummyDevice”的类,它实现了 ICustomDevice。
DummyDevice 和 ICustomDevice 都在同一个包“CustomDevicePackage”中。
所以在我的主程序中,我运行以下命令。
它总是返回 false,这意味着它没有找到“DummyDevice”
在我的 Eclipse 项目中,我在“src”创建了一个名为 META-INF 的文件夹,并在其下创建了一个名为“services”的子文件夹。
“服务”有一个名为“CustomDevicePackage.ICustomDevice”的文件,其中包含一行内容“CustomDevicePackage.DummyDevice”。
我做对了吗?我看到的每个关于 SPI 的例子都是关于加载 JARS。我没有加载 JAR,我正在尝试在同一个项目中运行一个类。此方法是否仅适用于加载 JAR?我希望我的程序支持加载本地子类和外部 JAR。
java - 为什么 ServiceLoader 总是重新实例化服务?
假设我有一个服务接口com.example.Service
。
对于测试,我定义了一个
包含的文件
实现MockServiceImpl
接口。
现在,当执行 aServiceLoader.load(Service.class)
并迭代结果时,myMockServiceImpl
总是会再次实例化。javadoc forServiceLoader
声明它确实维护了一个缓存,但我的模拟服务似乎没有被缓存。
为什么会这样,我如何获得ServiceLoader
缓存它?
java - 编写模块化 Java 应用程序
我有一个具有以下结构的项目:
模块使用ServiceLoader
机制来注册它们的服务。主类在main
模块中,该模块还负责使用ServiceLoader
机制在类路径中加载服务。问题是main
模块不知道module1
, module2
,module3
并且module4
因为它们是由用户独立安装的。我想要的是在启动程序时将这些模块中的所有类添加到类路径中,以便 ServiceLoader 知道这些模块中的服务。
目前,我在运行时从main
模块加载这些模块,但这似乎不是解决这个问题的好方法,因为 IDE 不知道这些模块,而且加载这些模块似乎需要更多时间运行。我已经研究过像 Elasticsearch 和 PrestoDB 这样的模块化 Java 项目是如何处理这个问题的,但似乎它们都在运行时加载了已安装的模块。
在开发模块化 Java 应用程序时如何处理这个问题?假设我有一个名为 plugins 的目录,其中包含用户安装的模块的 jar 文件,有没有办法使用 maven 插件使用包含该目录中所有 jar 的类路径来启动应用程序?还是我必须在运行时加载这些罐子?
scala - 在 Scala 和 SBT 中为 ServiceLoader 自动生成 META-INF/服务
在 Scala 和 SBT 中,有没有办法通过注释类自动生成META-INF/services/*
资源文件供以后使用,就像Google Auto Service对 Java 项目所做的那样?java.util.ServiceLoader
IE
META-INF/services/my.exported.ServiceInterface
在资源文件夹中自动生成文件。该文件将包含:
(我认为我不能直接使用 Google Auto Service,因为它不适用于 Scala 类——请参阅关于 realm-java github 问题的评论。)
java - tomcat 中的类加载器问题?(xercesImpl)
我有两个应用程序必须部署在同一个 tomcat(版本 7.0.56)上。
应用程序 A 使用 xerces(依赖于 xercesimpl.jar)。第二个应用程序 (B) 没有这种依赖关系,但正在做一些 xml 工作。
在服务器上单独部署应用程序 B 时,一切正常。在同一台服务器上部署应用程序 B 和应用程序 A 时,当应用程序 B 尝试执行其 xml 工作时出现异常:
这意味着在应用程序 B 中,服务器仍然看到 xercesimpl.jar/META-INF/services/javax.xml.parsers.SAXParserFactory
我正在通过 wtp 将tomcat与eclipse(mars)一起使用。任何人都有同样的问题或关于这种情况的任何信息?
对我来说,这意味着如果 tomcat 中的应用程序使用 xerces,那么同一服务器上的所有应用程序都必须使用 xerces。
java - java.util.ServiceLoader.load() 函数没用,只返回空结果
我正在尝试在 Scala 2.10 中使用 Java ServiceLoader 通过反射查找我的所有测试类:
我很确定“MyClass”有几个包含测试用例的子类,因为我可以使用“classOf[]”函数在同一个代码片段中找到它们
但是,我的测试总是以
ServiceLoader 在 Scala 中不起作用吗?如何解决或规避这个问题?
java - 可执行 jar 中的类路径设置似乎不适用于插件
我查看了这里和更广泛的网络以找到解决方案。有相关材料,但我一直找不到关于我的具体问题的任何有用信息。
我正在开发一些需要接受插件的 Java 软件。我不想使用像 OSGi 这样的花哨的框架,而 ServiceLoader 似乎提供了正确级别的支持。我基本上已经让它工作了,但是类路径有问题。我的目录结构如下:
progfolder
|___________ plugintest.jar
|___________/plugins
|________ plugin1.jar
|________ plugin2.jar
如果我运行 plugintest.jar ,java -jar plugintest.jar
那么即使我将 ./plugins/ (或它的变体)添加到清单中的 Class-Path: ,它也找不到插件。阅读表明这仅适用于类,而不适用于 jar,因此我尝试将两个插件中的类plugins
直接放在目录的完整路径中,但没有成功。
-cp plugins/*
如果我使用该-jar
选项,则不允许添加插件文件夹以将其添加到类路径中。为了解决这个问题,我可以运行 usingjava -cp plugintest.jar;plugins/* com.plugin.test.Main
并且按预期工作 - 这两个插件可以通过代码检测和访问,但是命令行有点笨拙,尽管我可以忍受它,如果它是最好的选择的话。
我找到了另一个解决方案,我为 中找到的 jar 创建了一个类加载器plugins
,它适用于这个简单的案例,但阅读表明我可能会在更复杂的应用程序中遇到安全问题。
有没有办法解决问题,这样我就可以简单地运行而java -jar plugintest.jar
无需自己加载类,或者这就是它的方式?
java - 运行 exec:java 时如何注册 SPI 实现
当通过Maven 插件运行时,我试图让VertX Mertrics工作。exec:java
当我将应用程序打包到 fatjar 并运行它时,一切都按预期工作java -jar fat.jar -conf config.json -Dvertx.metrics.options.enabled=true
当我运行它时,mvn clean package exec:java -DskipTests
我看到:
2016-03-22 18:39:58.833 WARN i.v.c.i.VertxImpl:348 - Metrics has been set to enabled but no VertxMetricsFactory found on classpath
我尝试了几种方法:
- 添加
io.vertx:vertx-dropwizard-metrics:3.2.1
为编译依赖 - 创建一个内部指标实现并通过
src/main/resources/META-INF/services/io.vertx.core.spi.VertxMetricsFactory
文件注册它(仔细检查它是否实际复制到target/classes/META-INF/services/io.vertx.core.spi.VertxMetricsFactory
) - 还添加
${basedir}/src/main/resources
为附加的类路径元素(除了上一点)
我已经仔细检查了ServiceLoader
实际上返回一个空迭代器的调试器。
这是我的执行插件配置:
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
<configuration>
<additionalClasspathElements>
<element>${basedir}/src/main/resources</element>
</additionalClasspathElements>
<mainClass>io.vertx.core.Launcher</mainClass>
<commandlineArgs>run ${vertx.mainVerticle} -conf ${vertx.config}</commandlineArgs>
<systemProperties>
<systemProperty>
<key>vertx.logger-delegate-factory-class-name</key>
<value>io.vertx.core.logging.SLF4JLogDelegateFactory</value>
</systemProperty>
<systemProperty>
<key>vertx.metrics.options.enabled</key>
<value>true</value>
</systemProperty>
</systemProperties>
</configuration>
</plugin>
这是确实有效exec:exec
的配置,但我想了解它是否以及为什么(不可能)使用它exec:java
<profile>
<id>exec</id>
<build>
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
<executions>
<execution>
<goals>
<goal>exec</goal>
</goals>
<phase>process-classes</phase>
<configuration>
<executable>java</executable>
<arguments>
<argument>-Dvertx.metrics.options.enabled=true</argument>
<argument>-Dvertx.logger-delegate-factory-class-name=${vertx.logger-delegate-factory-class-name}</argument>
<argument>-classpath</argument>
<classpath />
<argument>io.vertx.core.Launcher</argument>
<argument>run</argument>
<argument>${vertx.mainVerticle}</argument>
<argument>-conf</argument>
<argument>${vertx.config}</argument>
</arguments>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>