Java 如何在战争中从命令行运行类?

Java 如何在战争中从命令行运行类?,java,jar,war,Java,Jar,War,我有一个Java类,它有一个main,我曾经从命令行作为一个独立的应用程序运行 java -jar myjar.jar params 我需要重新打包代码,以便在apache下运行,我的所有代码,包括旧jar中的入口点类,最终都保存在WAR文件中,以便轻松解包到web服务器中 但是,我仍然希望能够从命令行运行它,代码没有改变,并且都在那里,我只是不知道如何让它运行 这是我试过的 我以为战争就像一个罐子,所以 java -jar mywar.war params 声明清单中没有定义主类失败 我手

我有一个Java类,它有一个main,我曾经从命令行作为一个独立的应用程序运行

java -jar myjar.jar params
我需要重新打包代码,以便在apache下运行,我的所有代码,包括旧jar中的入口点类,最终都保存在WAR文件中,以便轻松解包到web服务器中

但是,我仍然希望能够从命令行运行它,代码没有改变,并且都在那里,我只是不知道如何让它运行

这是我试过的

我以为战争就像一个罐子,所以

java -jar mywar.war params
声明清单中没有定义主类失败

我手动添加了一个清单到战争中,并再次尝试,效果相同

我注意到,在我的war中,我有一个名为META-INF的文件夹,其中包含manifest.mf,所以我在其中添加了一行,声明我的主类,就像在普通manifest中一样

Manifest-Version: 1.0
Main-Class: mypackage.MyEntryPointClass
这给出了一个
noClassDefFoundError mypackage.MyEntryPointClass
,这是一种进步。这让我相信这只是一个路径问题,所以我尝试了

Manifest-Version: 1.0
Main-Class: WEB-INF.classes.mypackage.MyEntryPointClass
我现在得到了相同的错误,但是有一个堆栈跟踪

Exception in thread "main" java.lang.NoClassDefFoundError: WEB-INF/classes/mypackage/MyEntryPointClass (wrong name: mypackage/MyEntryPointClass)
        at java.lang.ClassLoader.defineClass1(Native Method)
        at java.lang.ClassLoader.defineClass(Unknown Source)
        at java.security.SecureClassLoader.defineClass(Unknown Source)
        at java.net.URLClassLoader.defineClass(Unknown Source)
        at java.net.URLClassLoader.access$100(Unknown Source)
        at java.net.URLClassLoader$1.run(Unknown Source)
        at java.security.AccessController.doPrivileged(Native Method)
        at java.net.URLClassLoader.findClass(Unknown Source)
        at java.lang.ClassLoader.loadClass(Unknown Source)
        at sun.misc.Launcher$AppClassLoader.loadClass(Unknown Source)
        at java.lang.ClassLoader.loadClass(Unknown Source)
        at java.lang.ClassLoader.loadClassInternal(Unknown Source)
我已经在谷歌上搜索了一段时间,但找不到任何能回答我问题的答案,我在这里读到了一些稍有不同的问题,所以我想我会发布


Java 1.5,我不认为这有什么区别。

在归档文件中查找类的规则是,文件包声明的位置和归档文件中文件的位置必须匹配。由于您的类位于WEB-INF/classes中,它认为该类在当前上下文中运行无效

您可以执行要求的唯一方法是重新打包war,使
.class
文件位于存档根目录中的
mypackage
目录,而不是WEB-INF/classes目录。但是,如果这样做,您将无法再从任何web类访问该文件


如果你想在java命令行中同时使用这个类,请考虑建立一个可执行的jar,你可以从命令行运行,然后把那个jar放在战争> /Cord>文件的Web-INF/LIB目录下。如果你想拥有一个控制台/独立的应用程序,重用与你的WebApp相同的类,考虑把你的共享类打包在一个jar中,你可以把它放进<代码> WEB-INF/LIB 。然后从命令行使用该jar。 因此,您可以获得两个控制台应用程序,并且可以在servlet中使用相同的类,而无需制作两个不同的包。 当然,战争爆发时也是如此。

根据war文件,加载到类路径中的类位于“/WEB-INF/classes”和“/WEB-INF/lib”目录中

您可以尝试简单地将类的副本放在zip文件的根文件系统上(这就是war/jar)。但我不确定这是否有效

您始终可以创建两个单独的文件。

您可以执行(持续集成项目)所做的操作。 您可以下载一个war,它可以部署在tomcat中,也可以使用

java -jar hudson.war
(因为它有一个嵌入式Jetty引擎,从命令行运行它会导致服务器启动。)无论如何,通过查看hudson的清单,我了解到他们在根目录中放置了一个主类用于归档。在您的情况下,您的war布局应如下所示:

根目录下:

  • mypackage/MyEntryPointClass.class
  • WEB-INF/lib
  • WEB-INF/课程
  • META-INF/MANIFEST.MF
而清单应包括以下行:

Main-Class: mypackage.MyEntryPointClass
请注意,mypackage/MyEntryPointClass.class只能从命令行访问,而WEB-INF/classes下的类只能从应用程序服务器访问

HTH

在project中,您可以通过将
archiveclass
设置为
true
来自动构建jar。下面的例子

<plugin>
       <groupId>org.apache.maven.plugins</groupId>
       <artifactId>maven-war-plugin</artifactId>
       <configuration>
        <archiveClasses>true</archiveClasses>
       </configuration>
</plugin>

org.apache.maven.plugins
maven战争插件
真的
要从部署的war文件执行SomeClass.main(字符串[]args),请执行以下操作: 步骤1:编写具有main方法的类SomeClass.java,即(publicstaticvoidmain(String[]args){…}) 第二步:部署你的战争 步骤3:cd/usr/local/yourprojectsname/tomcat/webapps/projectName/WEB-INF 步骤4:java-cp“lib/jar1.jar:lib/jar2.jar:…:lib/jarn.jar”com.mypackage.SomeClass arg1 arg2。。。arg3 注1:(查看类SomeOtherClass.class是否在/usr/tomcat/webapps/projectName/WEB-INF/lib中)运行-->cd/usr/tomcat/webapps/projectName/WEB-INF/lib&& 找到-读取jarfile时命名“*.jar”;如果jar tf“$jarfile”| grep SomeOtherClass.class;然后回显“$jarfile”;fi;完成 注2:写入standard out,这样您就可以通过控制台上的打印语句来查看main是否实际工作。这叫做后门。
注3:Bozhidar Bozhanov的上述评论似乎是正确的

不可能从WAR文件运行java类。WAR文件的结构与Jar文件不同

要查找相关的java类,请将它们导出(使用ant的首选方式)为Jar,并将其放入web应用程序库中


然后您可以像平常一样使用jar文件来运行java程序。web应用程序中也引用了相同的jar(如果您将此jar放在web应用程序库中)

类似于Richard Detsch,但更易于理解(也适用于包)

步骤1:打开War文件

jar -xvf MyWar.war
步骤2:移动到目录中

cd WEB-INF
第三步:与所有依赖项一起运行main

java -classpath "lib/*:classes/." my.packages.destination.FileToRun

如果您使用的是Maven,只需遵循有关“”的
Maven war插件
文档:将
true
添加到插件的


...
mywebapp
1.0-快照
...
maven战争插件
2.6
真的
...
你将拥有的
    . start application from war file with java -jar file.war

    . put your war file in your favorite Web App server (like tomcat, ...)