如何从命令行在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中)