gpt4 book ai didi

java - 在交付单个 jar 并使用反射时,如何避免在命令行中指定完全限定的类名?

转载 作者:塔克拉玛干 更新时间:2023-11-02 07:54:43 27 4
gpt4 key购买 nike

我有一个代码库,我想生成几个可交付的 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>

稍后,我将创建一个 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>

一切正常,查看 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

现在,为了运行代码,我这样做:

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 应用程序和工具需要在命令行上指定类 - 而且它们都需要完全限定的类名也是。

如果这看起来不太像一个答案,我深表歉意,但我相信这是在这种情况下最好的行动方案。

关于java - 在交付单个 jar 并使用反射时,如何避免在命令行中指定完全限定的类名?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8823326/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com