Java 使用gradle构建ServiceLoader文件:如何?
我开始从一个著名的Java构建系统切换到Gradle来构建我的所有项目,在仅仅两个小时之后,我已经能够毫无问题地发布我的一个项目的新版本了——轻而易举 但现在我遇到了一个困难。简而言之,我需要复制为启用的服务生成必要文件的功能 简而言之:给定一个基类Java 使用gradle构建ServiceLoader文件:如何?,java,groovy,classloader,gradle,Java,Groovy,Classloader,Gradle,我开始从一个著名的Java构建系统切换到Gradle来构建我的所有项目,在仅仅两个小时之后,我已经能够毫无问题地发布我的一个项目的新版本了——轻而易举 但现在我遇到了一个困难。简而言之,我需要复制为启用的服务生成必要文件的功能 简而言之:给定一个基类foo.bar.MyClass,它会生成一个名为META-INF/services/foo.bar.MyClass的文件,其内容是当前项目中实现该接口/扩展该基类的一组类。这样的文件看起来像: com.mycompany.MyClassImpl or
foo.bar.MyClass
,它会生成一个名为META-INF/services/foo.bar.MyClass
的文件,其内容是当前项目中实现该接口/扩展该基类的一组类。这样的文件看起来像:
com.mycompany.MyClassImpl
org.othercompany.MyClassImpl
为了做到这一点,它使用我不知道什么作为类加载器,为com.myCompany.MyClassImpl
或任何东西加载Class
对象,并检查该类是否实现了所需的接口
我正试图在格拉德尔做同样的事情。几个小时的谷歌搜索让我想到了,但在和作者讨论了一下之后,这个插件似乎能够合并这些文件,而不是创建它们。所以,我必须自己去做
我对Gradle和Groovy都是一个真正的初学者,这并没有帮助!这是我当前的代码,链接到完整的build.gradle
;如下所示的输出(我设法获得了输出;从一个干净的目录中无法工作)(请容忍我……我使用Java,我非常高兴;Groovy对我来说是全新的):
输出:
com.github.fge.msgsimple.InternalBundle
failed to load com.github.fge.msgsimple.bundle.MessageBundle: java.lang.NoClassDefFoundError: com/github/fge/Frozen
failed to load com.github.fge.msgsimple.bundle.MessageBundleBuilder: java.lang.NoClassDefFoundError: com/github/fge/Thawed
com.github.fge.msgsimple.bundle.PropertiesBundle$1
com.github.fge.msgsimple.bundle.PropertiesBundle
com.github.fge.msgsimple.provider.MessageSourceProvider
com.github.fge.msgsimple.provider.LoadingMessageSourceProvider$1
com.github.fge.msgsimple.provider.LoadingMessageSourceProvider$2
com.github.fge.msgsimple.provider.LoadingMessageSourceProvider$3
com.github.fge.msgsimple.provider.LoadingMessageSourceProvider$Builder
com.github.fge.msgsimple.provider.LoadingMessageSourceProvider
com.github.fge.msgsimple.provider.MessageSourceLoader
com.github.fge.msgsimple.provider.StaticMessageSourceProvider$Builder
com.github.fge.msgsimple.provider.StaticMessageSourceProvider$1
com.github.fge.msgsimple.provider.StaticMessageSourceProvider
com.github.fge.msgsimple.source.MessageSource
com.github.fge.msgsimple.source.MapMessageSource$Builder
com.github.fge.msgsimple.source.MapMessageSource$1
com.github.fge.msgsimple.source.MapMessageSource
com.github.fge.msgsimple.source.PropertiesMessageSource
com.github.fge.msgsimple.locale.LocaleUtils
com.github.fge.msgsimple.serviceloader.MessageBundleFactory
com.github.fge.msgsimple.serviceloader.MessageBundleProvider
:compileJava UP-TO-DATE
问题出在前两行:冻结
和解冻
在另一个项目中,该项目位于编译类路径中,但不在我迄今为止设法获取的类路径中。。。因此,这些类甚至无法加载
如何修改该代码以获得完整的编译类路径?这是我的第一个问题。第二个问题:当代码工作时,如何将其插入到构建过程中?以下是一些提示:
- 创建一个新的
,而不是重用现有的URLClassLoader
- 使用
(一个sourceset.main.compileClasspath
)而不是Iterable
初始化类加载器classesDir
- 将代码转换为Gradle任务类。有关更多信息,请参阅中的“编写简单任务类”
理想情况下,您应该使用类似ASM的库来分析代码,而不是使用类加载器。为了避免由于类内部引用不在编译类路径上的类而无法加载该类的情况,您可能需要使用
sourceset.main.runtimeClasspath
来初始化类加载器。好的,我尝试了以下方法:sourceset.main.compileClasspath.each{println(it)}
-->它只打印我所依赖的罐子。。。所以,基本上,我必须用这些创建jar URL,并将其输入到我创建的新类路径中,对吗?我创建了一个URL
的Java数组(在Groovy中如何做到这一点?),使用URLClassLoader.newInstance()
,我应该可以更进一步了?(感谢用户指南链接,我也会读到的,我只是想先把“类检测”的事情做好!)实际上你也需要classesDir
。可能最好使用runtimeClasspath
初始化类加载器,它已经包含classesDir
。要将列表转换为数组,请使用列表作为URL[]
。如果您对Java感到更满意,可以用Java编写任务类好奇:如何使用runtimeClasspath
启动类加载器?我猜剩下的就是URLClassLoader
实例上的.addURL()
。addURL
是一个受保护的方法,您不应该调用它。在Groovy中,您可以使用类似于的新URLClassLoader(runtimeClasspath.collect{it.toURI().toURL()}作为URL[])
。。。我只能向你鞠躬,感谢你的大力帮助!
com.github.fge.msgsimple.InternalBundle
failed to load com.github.fge.msgsimple.bundle.MessageBundle: java.lang.NoClassDefFoundError: com/github/fge/Frozen
failed to load com.github.fge.msgsimple.bundle.MessageBundleBuilder: java.lang.NoClassDefFoundError: com/github/fge/Thawed
com.github.fge.msgsimple.bundle.PropertiesBundle$1
com.github.fge.msgsimple.bundle.PropertiesBundle
com.github.fge.msgsimple.provider.MessageSourceProvider
com.github.fge.msgsimple.provider.LoadingMessageSourceProvider$1
com.github.fge.msgsimple.provider.LoadingMessageSourceProvider$2
com.github.fge.msgsimple.provider.LoadingMessageSourceProvider$3
com.github.fge.msgsimple.provider.LoadingMessageSourceProvider$Builder
com.github.fge.msgsimple.provider.LoadingMessageSourceProvider
com.github.fge.msgsimple.provider.MessageSourceLoader
com.github.fge.msgsimple.provider.StaticMessageSourceProvider$Builder
com.github.fge.msgsimple.provider.StaticMessageSourceProvider$1
com.github.fge.msgsimple.provider.StaticMessageSourceProvider
com.github.fge.msgsimple.source.MessageSource
com.github.fge.msgsimple.source.MapMessageSource$Builder
com.github.fge.msgsimple.source.MapMessageSource$1
com.github.fge.msgsimple.source.MapMessageSource
com.github.fge.msgsimple.source.PropertiesMessageSource
com.github.fge.msgsimple.locale.LocaleUtils
com.github.fge.msgsimple.serviceloader.MessageBundleFactory
com.github.fge.msgsimple.serviceloader.MessageBundleProvider
:compileJava UP-TO-DATE