如何从命令行在WAR中运行一个类?
我有一个Java类有一个主,我曾经作为一个独立的应用程序从命令行运行,例如
java -jar myjar.jar params
我需要重新打包代码,以便在apache下运行,包括来自旧jar的入口点类的所有代码都已经放在WAR文件中,以便轻松地将其卸载到Web服务器中。
不过,我仍然希望能够从命令行运行它,并且代码没有改变,并且都在那里,我只是不知道如何让它运行。
这是我试过的…
我推测战争就像一个jar子,所以
java -jar mywar.war params
那失败了,说清单中没有定义主类。
我手动添加了一个战争清单,并再次尝试,具有相同的效果。
我注意到,在我的战争中,我有一个名为META-INF的文件夹包含manifest.mf,所以我添加了一行来声明我的主类,因为我会正常清单…
Manifest-Version: 1.0 Main-Class: mypackage.MyEntryPointClass
这给了一个noClassDefFoundError mypackage.MyEntryPointClass
,这是一个sorting的进度。 这让我相信这只是一个path问题,所以我试了一下
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)
我已经search了一下,但找不到任何回答我的问题,我读了一些其他问题,这些稍有不同,所以我想我会后。
Java 1.5,不是我认为应该有所作为。
你可以做什么哈德森 (持续集成项目)。 你下载一个可以在tomcat中部署的战争或执行使用
java -jar hudson.war
(因为它有一个embedded式的Jetty引擎,所以从命令行运行它会导致一个服务器被启动。)无论如何,通过查看哈德森的清单,我明白他们把一个Main类放在归档的根目录下。 在你的情况下,你的战争布局应该是这样的:
根源:
- mypackage中/ MyEntryPointClass.class
- WEB-INF / lib目录
- WEB-INF / classes目录
- META-INF / MANIFEST.MF
而清单应包括以下行:
Main-Class: mypackage.MyEntryPointClass
请注意,mypackage / MyEntryPointClass.class只能从命令行访问,而WEB-INF / classes下的类只能从应用程序服务器访问。
HTH
一场战争是一个Web应用程序。 如果你想让一个控制台/独立应用程序重用与你的webapp相同的类,可以考虑将你的共享类打包成一个jar文件,你可以把它放在WEB-INF/lib
。 然后从命令行使用该jar。 因此,您可以同时获得控制台应用程序,并且可以在servlet中使用相同的类,而无需创build两个不同的包。 当战争爆炸时,这当然是正确的。
要从已部署的war文件执行SomeClass.main(String [] args),请执行以下操作:
步骤1: 编写具有主要方法方法的类SomeClass.java ie(public static void main(String [] args){…})
第2步: 部署您的WAR
步骤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 :(查看/ usr / tomcat / webapps / projectName / WEB-INF / lib中的类SomeOtherClass.class)
运行 – > cd / usr / tomcat / webapps / projectName / WEB-INF / lib && find。 -name'* .jar'| 同时读取jarfile; 如果jar tf“$ jarfile”| grep SomeOtherClass.class; 然后echo“$ jarfile”; networking连接; DONE
注2:写出标准出来,你可以看到你的主实际上通过打印语句工作到控制台。 这被称为后门。
注3:Bozhidar Bozhanov上面的评论似乎是正确的
在归档文件中查找类的规则是,文件的包声明的位置和归档文件中的文件的位置必须匹配。 由于您的类位于WEB-INF / classes中,因此认为该类在当前上下文中无效。
唯一可以做的就是重新打包战争,这样.class
文件就驻留在归档根目录的mypackage
目录中,而不是WEB-INF / classes目录中。 但是,如果你这样做,你将无法从任何networking课程访问该文件了。
如果您想在java命令行的战争和外部重用这个类,请考虑构build一个可以从命令行运行的可执行jar,然后将该jar放入war
文件的WEB-INF / lib目录中。
类似理查德Detsch但更容易跟随(与包装一起工作)
步骤1:解开War文件。
jar -xvf MyWar.war
第2步:进入目录
cd WEB-INF
第三步:运行你所有的依赖关系
java -classpath "lib/*:classes/." my.packages.destination.FileToRun
在Maven项目中,您可以使用Maven War插件通过将archiveClasses
设置为true
来自动构buildjar。 下面的例子。
<plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-war-plugin</artifactId> <configuration> <archiveClasses>true</archiveClasses> </configuration> </plugin>
如果你正在使用Maven,只需按照maven-war-plugin
文档中关于“ 如何创build一个包含我的webapp中的类的JAR ”:将<attachClasses>true</attachClasses>
到插件的<configuration>
:
<project> ... <artifactId>mywebapp</artifactId> <version>1.0-SNAPSHOT</version> ... <build> <plugins> <plugin> <artifactId>maven-war-plugin</artifactId> <version>2.6</version> <configuration> <attachClasses>true</attachClasses> </configuration> </plugin> </plugins> </build> ... </project>
你将在target/
文件夹中有2个产品:
-
project.war
本身 -
project-classes.jar
包含所有在jar中编译的类
然后你将能够使用经典的方法执行一个主类: java -cp target/project-classes.jar 'com.mycompany.MainClass' param1 param2
那么,根据维基百科 ,带有WAR文件,加载到类path中的类位于“/ WEB-INF / classes”和“/ WEB-INF / lib”目录中。
你可以尝试简单地把一个类的副本放在zip文件的根文件系统上(这是一个war / jar)。 我不确定这是否会工作。
你总是可以创build两个单独的文件。
从WAR文件运行java类是不可能的。 WAR文件与Jar文件有不同的结构。
要find相关的java类,导出(首选的方式来使用ant)他们作为Jar把它放在你的Web应用程序库。
然后你可以像平常一样使用jar文件来运行java程序。 Web应用程序也提到了同样的jar(如果你把这个jar放在web app lib中)