某些背景: 我在Eclipse中创建了一个Java项目(仅使用Eclipse一周)。我在13年的间歇后选择了Java,因为我不得不转换来自IBM EBCDIC 5035& 935到UTF-16。独立的类(总共两个类)在Eclipse中运行良好。 每个类都有两个参数 - 源文件+位置和目标文件+位置 每个班级每晚都会转换十几个文件。
所以现在我必须自动化解决方案并进行部署。我使用Eclipse创建一个常规jar(不是一个可运行的jar),这样我就可以单独调用每个类而不创建一个“manager”类。
在运行以下命令时在命令提示符下:
java -jar test.jar ConvFileCP_5035_To_UTF16 \\\\ usanofp03 \\ Informatica \\ Dev \\ OutputFiles \\ JDEJapanCustomer_CP939.txt \\\\ usanofp03 \\ Informatica \\ Dev \\ OutputFiles \\ JDEJapanCustomer。 TXT
输出(用system.out确认......)让我感到惊讶,因为 args [0] = ConvFileCP_5035_To_UTF16(班级名称!)和 args [1] = \\\\ usanofp03 \\ Informatica \\ Dev \\ OutputFiles \\ JDEJapanCustomer_CP939.txt
我转向使用args [1]和args [2]并且程序工作但我想知道为什么会发生这种情况以及在这里做什么是正确的
帮助将不胜感激! 谢谢,
答案 0 :(得分:2)
注意:我意识到这是一个老问题,但确实值得回答。
虽然提问者说他们“使用Eclipse来创建一个普通的jar(不是一个可运行的jar)”,但看起来Eclipse可能实际上已经指定了他们的一个类作为主要的类。 JAR,它解释了他们所经历的输出,即args[0]
持有他们打算运行的类的名称。
-jar
选项指示java
“运行”给定的JAR,这实际上导致java
查看位于给定JAR内的清单中的一行,该行指定了主要班级。运行JAR时,任何进一步的参数都将传递给清单指定的主类。
继 @fge 之后所说的,看起来提问者的体验可能是运行一个意外制造的可运行的JAR的结果,而JAR应该被用作库,用-classpath
选项,在调用java
并提供目标类时。
有关进一步调查,请参阅以下示例。
使用以下类来枚举它收到的命令行参数,我们可以演示不同的java
调用的行为:
public class JarTest
{
public static void main(String[] args)
{
for(int i = 0; i < args.length; i++)
{
System.out.println(i + ": " + args[i]);
}
}
}
正常编译此类(即javac JarTest.java
),我们可以通常的方式运行它并提供一些命令行参数来查看它的行为:
~/temp/jar-test$ java JarTest arg1 arg2
0: arg1
1: arg2
以下命令将此类打包为基本JAR:
~/temp/jar-test$ jar cf jar-test.jar JarTest.class
The Java Tutorials Running JAR-Packaged Software章的最后一节,标题为“JAR Files as Applications”,解释了直接“运行JAR打包应用程序”的唯一方法是-jar
选项如下所示:
~/temp/jar-test$ java -jar jar-test.jar
no main manifest attribute, in jar-test.jar
但是,正如我们上面所看到的,这并不容易。另请注意,即使明确指定预期的主类也无济于事:
~/temp/jar-test$ java -jar jar-test.jar JarTest arg1 arg2
no main manifest attribute, in jar-test.jar
正如我们将在下面看到的,这是因为在指定的JAR之后的任何内容成为主类的命令行参数(如果找到),因此java
命令本身会有效地忽略它。当然,在上面的例子中,这些参数实际上并没有传递给任何东西,因为java
还不知道它应该传递给哪个类。
为了实际运行JAR,java
命令需要知道哪个类是应用程序的入口点(即具有main方法的类),这是通过{{1在JAR的清单中指定的。标头。如果不指定主类,我们会看到上面的错误。 The Java Tutorials的Setting an Application's Entry Point章节描述了如何在JAR的清单中指定主类。按照这些说明,我们使用以下内容创建Main-Class
(包括最终换行符):
manifest.txt
重新创建JAR并包含清单(有关jar命令的更多详细信息,请参阅this和this):
Main-Class: JarTest
现在我们可以尝试运行新的JAR:
~/temp/jar-test$ jar cfm jar-test.jar manifest.txt JarTest.class
正如我们所看到的,我们的JAR现在成功运行,输出类似于提问者的好奇输出。当运行通过包含的清单指定主类的JAR时,不需要指定目标类,实际上如果我们这样做,该字符串将作为~/temp/jar-test$ java -jar jar-test.jar JarTest arg1 arg2
0: JarTest
1: arg1
2: arg2
传递给主类。
为了达到预期的结果,我们应该通过将JAR添加到类路径来运行我们的程序(最简单的方法是通过args[0]
或-classpath
选项)并指定类到运行:
-cp
如果我们将它与前一个命令进行比较,唯一的区别是我们使用了~/temp/jar-test$ java -cp jar-test.jar JarTest arg1 arg2
0: arg1
1: arg2
选项,而现在我们使用了-jar
选项并实现了提问者的意图。
这里值得注意的是,上面的(-cp
)方法可以使用基本JAR(即没有明确指定的主类的JAR)或可运行的JAR,因为我们现在只是告诉{ {1}}在给定的JAR中查找指定的类。