Liv*_*ing 3 java ant reflection classpath
我有一个代码库,我想生成几个可交付的jar文件,每个文件都要从命令行运行,并访问代码库的某些功能.运行时,一些命令行参数是jar中的其他类,然后由反射创建.它工作得很好,但我必须指定类的非常长的完全限定路径,即使这些类在jar文件中.
我使用ant编译然后jar一系列目录.从最小的示例build.xml文件:
<property name="build" location="build"/>
<property name="jars" location="${build}/jars"/>
<property name="classes" location="${build}/classes"/>
<property name="src" location="src/dom/place/proj"/>
<target name="utility">
<javac
includeantruntime="false"
srcdir="${src}/utility" destdir="${classes}"
classpathref="classpath" />
<jar
destfile="${jars}/utility.jar"
basedir="${classes}"
includes="**/utility/**" />
</target>
<target name="tokenizers" depends="utility">
<javac
includeantruntime="false"
srcdir="${src}/tokenizers"
destdir="${classes}"
classpathref="classpath" />
<jar
destfile="${jars}/tokenizers.jar"
basedir="${classes}"
includes="**/tokenizers/**" />
</target>
Run Code Online (Sandbox Code Playgroud)
后来,我正在创建一个包含所有必需类的jar文件,并将运行一个命令,例如:
<target name="tokenize-file-jar">
<jar destfile="${dist}/TokenizeFile.jar">
<zipgroupfileset dir="${jars}">
<include name="utility.jar"/>
<include name="tokenizers.jar"/>
</zipgroupfileset>
<manifest>
<attribute name="Main-Class" value="dom.place.proj.tokenizers.TokenizeFile"/>
</manifest>
</jar>
</target>
Run Code Online (Sandbox Code Playgroud)
这一切都有效,并查看jar文件,所有类都在那里.
prompt > unzip -l TokenizeFile.jar
Archive: TokenizeFile.jar
Length Date Time Name
-------- ---- ---- ----
0 01-11-12 11:07 META-INF/
286 01-11-12 11:07 META-INF/MANIFEST.MF
0 01-11-12 10:16 dom/
0 01-11-12 10:16 dom/place/
0 01-11-12 10:16 dom/place/proj/
0 01-11-12 10:16 dom/place/proj/tokenizers/
1737 01-11-12 11:07 dom/place/proj/tokenizers/FileTokenizer.class
1411 01-11-12 11:07 dom/place/proj/tokenizers/PorterTokenizer.class
1754 01-11-12 11:07 dom/place/proj/tokenizers/TokenizeFile.class
992 01-11-12 11:07 dom/place/proj/tokenizers/Tokenizer.class
0 01-11-12 10:16 dom/place/proj/utility/
1106 01-11-12 11:07 dom/place/proj/utility/BoundedExecutor.class
3128 01-11-12 11:07 dom/place/proj/utility/Converter.class
1107 01-11-12 11:07 dom/place/proj/utility/ExceptionHandler.class
Run Code Online (Sandbox Code Playgroud)
现在,为了运行代码,我做:
java -jar TokenizeFile.jar test.txt dom.place.proj.tokenizers.FileTokenizer dom.place.proj.tokenizers.PorterTokenizer
它的工作原理.好极了!但我希望我的客户端不必在命令行上为每个类指定完全限定名称 - 这是一个小例子,可能有很多项.在我的代码或构建过程中,我可以更改以允许这样做:
java -jar TokenizeFile.jar test.txt FileTokenizer PorterTokenizer
谢谢你的帮助.到目前为止,我正在从C++/make转换到像ant和Java一样.
简短而简单的答案是,这是不可能的; 类名也只是在他们的包中也是明确的.
让调用者更简单的一个选择是让你的应用程序"dom.place.proj.tokenizers."在它们提供的每个类参数前面加上- 所以你的简短首选示例的行为与第一个相同.
然而,非常简单,功率降低; 用户不再可能定义自己的自定义类并将其传入,因为包不匹配.(在某种程度上,如果类名不包含句点(.),你可以通过仅预先设置默认包来解决这个问题,但是你添加的特殊情况越多,这将是理解......)
你提到你正在转向Java.在一天结束的时候,我希望在这样的情况下出现由其完整的包装前缀名称指定的类,因此缩写版本可能会让习惯于Java的人更加困惑.
因此,我的建议是保留现状,并且基本上更习惯于命令行的第一个版本.即使您要解决此特定情况下的问题,还有许多其他第一方和第三方Java应用程序和工具需要在命令行中指定类 - 并且它们都需要完全限定的类名太.
如果这看起来不像答案那么道歉,但我相信这是这种情况下最好的行动方案.