Managing Data Dependecies of Java Classes that Load Data from the Classpath at Runtime
What is the simplest way to manage dependencies of Java 开发者_Go百科classes to data files present in the classpath?
More specifically:
How should data dependencies be annotated? Perhaps using Java annotations (e.g., @Data)? Or rather some build entries in a build script or a properties file? Is there build tool that integrates and evaluates such information (Ant, Scons, ...)? Do you have examples?Consider the following scenario:
A few lines of Ant create a Jar from my sources that includes everything found on the classpath. Then jarjar is used to remove all .class files that are not necessary to execute, say, class Foo. The problem is that all the data files that class Bar depends upon are still there in the Jar. The ideal deployment script, however, would recognize that the data files on which only class Bar depends can be removed while data files on which class Foo depends must be retained.Any hints?
This is one of the many problems Maven has already solved with it's build, dependency, and resource management. Any maven project follows a standard directory layout which dictates where you should put your Data files: in the 'resources' directories. The conventional Maven directory structure is as follows...
/
/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
The benefit of this is that all files which are contained in the 'main' (prod) resources directories are available to your application at run-time from the Classpath. All of the 'test/resources' files are available to your code during build & unit test time but are NOT included in your final artifact.
I don't think a generic solution exists for the system you describe, however, I just had a stab at reading annotations on classes using ASM, since that is used by jarjar as well. It is not hard to read the annotation data that way (pass in a ClassVisitor to the accept() method on ClassReader, and do something useful on the visitAnnotation callback). This means you can either try and include your intended behavior to jarjar or you could add it as a custom step to your build process.
Can't you refactor your project so that you have submodules that each contain the relevant files for the project itself ; Bar class and Bar related files will be packaged in their bundle while Foo ones will packed into another?
Another possibility would be to use some package naming convention to be able to filter the files you want to see i your bundles.
精彩评论