在运行时从类路径加载数据的Java类的数据依赖管理

9
什么是管理Java类依赖于类路径中存在的数据文件的最简单方法?
更具体地说,应该如何注释数据依赖关系?可以使用Java注释(例如@Data)还是构建脚本或属性文件中的一些构建条目?是否有构建工具集成和评估这些信息(Ant、Scons等)?您有示例吗?
考虑以下场景:几行Ant从我的源代码创建一个Jar文件,其中包括在类路径中找到的所有内容。然后使用jarjar删除不必要执行的所有.class文件,例如类Foo。问题是,类Bar依赖的所有数据文件仍然存在于Jar文件中。然而,理想的部署脚本将识别只有类Bar依赖的数据文件可以被删除,而必须保留类Foo依赖的数据文件。
有任何提示吗?
3个回答

1

这是Maven已经通过其构建、依赖和资源管理解决的众多问题之一。任何Maven项目都遵循标准的目录布局,该布局规定了您应该将数据文件放在哪里:即“资源”目录中。传统的Maven目录结构如下所示...

/
/src/
/src/main/java/
/src/main/java/App.java
/src/main/resources/
/src/main/resources/my.prod.data.or.cfg.or.whatever
/src/test/java/
/src/test/java/AppTest.java
/src/test/resources/
/src/test/resources/my.test.data.or.cfg.or.whatever
/pom.xml

这样做的好处是,所有包含在“main”(prod)资源目录中的文件都可以在运行时从类路径中对您的应用程序进行访问。所有“test/resources”文件都可以在构建和单元测试期间对您的代码进行访问,但不会包含在最终的构件中。

谢谢您的回答,但恐怕这并不能解决问题:Maven是否明确地注释了App.java与my.prod.data.or.cfg.or.whatever之间的依赖关系?如果前者在部署过程中被排除,Maven是否会自动忽略后者? - Martin Potthast
我不知道是否有任何内置的注释可以提供您所需的功能。但是,使用我上面解释的maven解决方案,您可以使用以下代码行:ClassLoader.getSystemResource("classpath:/my.prod.data.or.cfg.or.whatever")' classpath:/'部分是可选的,因为默认情况下它首先查找类路径,但我喜欢明确说明。考虑到这一点,编写自己的注释以包装此实现应该不太困难。查看ClassLoader API以获取有关此功能及其其他方法的更多信息。希望这能帮助您朝着正确的方向前进。 - Jesse Webb
将数据与代码分离是个好主意,但这并不能解决维护数据和类之间强关联的问题。总之,不幸的是,Maven 不支持此功能。难道真的没有构建系统实现这个解决方案吗? - Martin Potthast

0

你不能重构你的项目,这样你就可以有子模块,每个子模块都包含项目本身的相关文件;Bar类和与之相关的文件将被打包在它们的捆绑包中,而Foo类将被打包到另一个捆绑包中吗?

另一种可能性是使用一些包命名约定,以便能够过滤你想要在捆绑包中看到的文件。


这将隐式地模拟类对数据的依赖关系,但在极端情况下,这意味着每个类一个项目,这是不可行的。此外,我不希望我的数据依赖关系决定我的组件布局。那么,最简单和最常用的显式建模代码数据依赖关系的方法是什么?感谢您的帮助! - Martin Potthast

0

我认为针对您所描述的系统并不存在通用解决方案,但是我刚刚尝试使用ASM读取类上的注释,因为jarjar也使用了它。通过这种方式读取注释数据并不难(将ClassVisitor传递给ClassReader的accept()方法,并在visitAnnotation回调中执行有用的操作)。这意味着您可以尝试将您想要的行为包含到jarjar中,或者将其作为自定义步骤添加到构建过程中。


这听起来是一个有趣的方法。谢谢!不过我并不完全满意,因为我必须自己完成所有的工作,并且解决方案将是专有的。 - Martin Potthast

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接