Java 如何从命令行在 WAR 中运行类?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1842972/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How do I run a class in a WAR from the command line?
提问by Simon
I have a Java class which has a main and I used to run as a standalone app from the command line e.g.
我有一个 Java 类,它有一个 main,我曾经从命令行作为独立应用程序运行,例如
java -jar myjar.jar params
I needed to repackage the code to run under apache and all my code, including the entry point class from the old jar, has ended up in a WAR file for easy deplyment into the web server.
我需要重新打包代码以在 apache 下运行,并且我的所有代码,包括来自旧 jar 的入口点类,都以 WAR 文件结束,以便轻松部署到 Web 服务器中。
However, I still want to be able to run it from the command line and the code has not changed and is all in there, I just can't figure out how to get it to run.
但是,我仍然希望能够从命令行运行它并且代码没有改变并且全部在那里,我只是不知道如何让它运行。
Here's what I tried...
这是我尝试过的...
I presumed the WAR was just like a jar, so
我认为战争就像一个罐子,所以
java -jar mywar.war params
That failed saying there was no main class defined in the manifest.
未能说明清单中没有定义主类。
I manually added a manifest to the war and tried again, with the same effect.
我手动向战争添加了一个清单并再次尝试,具有相同的效果。
I noticed that in my war I had a folder called META-INF containing a manifest.mf, so I added a line to that declaring my main class as I would to a normal manifest...
我注意到在我的战争中我有一个名为 META-INF 的文件夹,其中包含一个 manifest.mf,所以我添加了一行来声明我的主类,就像我对普通清单一样......
Manifest-Version: 1.0
Main-Class: mypackage.MyEntryPointClass
This gave a noClassDefFoundError mypackage.MyEntryPointClass
, which is progress of a sort. That led me to believe that it was just a path issue, so I tried
这给出了noClassDefFoundError mypackage.MyEntryPointClass
,这是一种进步。这让我相信这只是一个路径问题,所以我尝试了
Manifest-Version: 1.0
Main-Class: WEB-INF.classes.mypackage.MyEntryPointClass
I now get the same error, but with a stack trace...
我现在得到同样的错误,但有一个堆栈跟踪......
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.access0(Unknown Source)
at java.net.URLClassLoader.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)
I've googled for a bit but can't find anything which answers my question, and I read a couple of other questions here which are slightly different, so I thought I would post.
我用谷歌搜索了一下,但找不到任何可以回答我的问题的内容,我在这里阅读了一些其他问题,这些问题略有不同,所以我想我会发布。
Java 1.5, not that I think that should make any difference.
Java 1.5,不是我认为应该有什么不同。
回答by Jason Gritman
The rules of locating classes in an archive file is that the location of the file's package declaration and the location of the file within the archive have to match. Since your class is located in WEB-INF/classes, it thinks the class is not valid to run in the current context.
在存档文件中定位类的规则是文件的包声明的位置和存档中文件的位置必须匹配。由于您的类位于 WEB-INF/classes 中,因此它认为该类在当前上下文中运行无效。
The only way you can do what you're asking is to repackage the war so the .class
file resides in the mypackage
directory in the root of the archive rather than the WEB-INF/classes directory. However, if you do that you won't be able to access the file from any of your web classes anymore.
您可以执行您所要求的唯一方法是重新打包战争,以便.class
文件驻留在mypackage
存档根目录中的目录中,而不是 WEB-INF/classes 目录中。但是,如果这样做,您将无法再从任何 Web 类访问该文件。
If you want to reuse this class in both the war and outside from the java command line, consider building an executable jar you can run from the command line, then putting that jar in the war
file's WEB-INF/lib directory.
如果您想从 java 命令行在 war 和外部重用此类,请考虑构建一个可以从命令行运行的可执行 jar,然后将该 jar 放在war
文件的 WEB-INF/lib 目录中。
回答by Bozho
A war is a webapp. If you want to have a console/standalone application reusing the same classes as you webapp, consider packaging your shared classes in a jar, which you can put in WEB-INF/lib
. Then use that jar from the command line.
Thus you get both your console application, and you can use the same classes in your servlets, without making two different packages.
This, of course, is true when the war is exploded.
战争是一个网络应用程序。如果您想让控制台/独立应用程序重用与 web 应用程序相同的类,请考虑将共享类打包在 jar 中,您可以将其放入WEB-INF/lib
. 然后从命令行使用该 jar。因此,您可以获得控制台应用程序,并且可以在 servlet 中使用相同的类,而无需制作两个不同的包。当然,这在战争爆发时是正确的。
回答by Chad Okere
Well, according to Wikipedia, with a WAR file, the classes that get loaded into the classpath are in the "/WEB-INF/classes" and "/WEB-INF/lib" directory.
好吧,根据Wikipedia,使用 WAR 文件,加载到类路径中的类位于“/WEB-INF/classes”和“/WEB-INF/lib”目录中。
You could try simply putting a copy of the classes on the root file system of the zip file (which is what a war/jar is). I'm not sure if that would work though.
您可以尝试简单地将类的副本放在 zip 文件的根文件系统上(这就是 war/jar 的内容)。我不确定这是否可行。
You can always just create two separate files.
您始终可以只创建两个单独的文件。
回答by Yonatan Maman
You can do what Hudson(continuous integration project) does. you download a war which can be deployed in tomcat or to execute using
您可以执行Hudson(持续集成项目)所做的工作。你下载一个可以部署在 tomcat 中或使用执行的战争
java -jar hudson.war
(Because it has an embedded Jetty engine, running it from command line cause a server to be launched.) Anyway by looking at hudson's manifest I understand that they put a Main class in the root for the archive. In your case your war layout should be look like:
(因为它有一个嵌入式 Jetty 引擎,从命令行运行它会导致启动服务器。)无论如何,通过查看 hudson 的清单,我知道他们将 Main 类放在存档的根目录中。在您的情况下,您的战争布局应如下所示:
under root:
在根下:
- mypackage/MyEntryPointClass.class
- WEB-INF/lib
- WEB-INF/classes
- META-INF/MANIFEST.MF
- mypackage/MyEntryPointClass.class
- 网络信息/库
- WEB-INF/类
- 元信息/清单.MF
while the manifest should include the following line:
而清单应包括以下行:
Main-Class: mypackage.MyEntryPointClass
please notice that the mypackage/MyEntryPointClass.class is accessable from the command line only, and the classes under WEB-INF/classes are accessable from the application server only.
请注意 mypackage/MyEntryPointClass.class 只能从命令行访问,而 WEB-INF/classes 下的类只能从应用服务器访问。
HTH
HTH
回答by marioosh
In Mavenproject, You can build jar automatically using Maven War pluginby setting archiveClasses
to true
. Example below.
在Maven项目中,您可以通过设置为.jar 使用Maven War 插件自动构建 jar 。下面举例。archiveClasses
true
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<configuration>
<archiveClasses>true</archiveClasses>
</configuration>
</plugin>
回答by Richard Detsch
To execute SomeClass.main(String [] args) from a deployed war file do:
要从部署的 war 文件执行 SomeClass.main(String [] args),请执行以下操作:
Step 1: Write class SomeClass.java that has a main method method i.e. (public static void main(String[] args) {...})
第 1 步:编写类 SomeClass.java,它有一个 main 方法方法,即 (public static void main(String[] args) {...})
Step 2: Deploy your WAR
第 2 步:部署您的 WAR
Step 3: cd /usr/local/yourprojectsname/tomcat/webapps/projectName/WEB-INF
第三步:cd /usr/local/yourprojectsname/tomcat/webapps/projectName/WEB-INF
Step 4:java -cp "lib/jar1.jar:lib/jar2.jar: ... :lib/jarn.jar" com.mypackage.SomeClass arg1 arg2 ... arg3
第 4 步:java -cp "lib/jar1.jar:lib/jar2.jar: ... :lib/jarn.jar" com.mypackage.SomeClass arg1 arg2 ... arg3
Note1: (to see if the class SomeOtherClass.class is in /usr/tomcat/webapps/projectName/WEB-INF/lib)
注1:(查看类SomeOtherClass.class是否在/usr/tomcat/webapps/projectName/WEB-INF/lib中)
run --> cd /usr/tomcat/webapps/projectName/WEB-INF/lib && find . -name '*.jar' | while read jarfile; do if jar tf "$jarfile" | grep SomeOtherClass.class; then echo "$jarfile"; fi; done
运行 --> cd /usr/tomcat/webapps/projectName/WEB-INF/lib && find 。-name '*.jar' | 读取 jarfile 时;do if jar tf "$jarfile" | grep SomeOtherClass.class; 然后 echo "$jarfile"; fi; 完毕
Note2: Write to standard out so you can see if your main actually works via print statements to the console. This is called a back door.
注意2:写入标准输出,以便您可以通过控制台的打印语句查看您的主要内容是否确实有效。这称为后门。
Note3: The comment above by Bozhidar Bozhanov seems correct
注3: Bozhidar Bozhanov 上面的评论似乎是正确的
回答by Rawat
It's not possible to run a java class from a WAR file. WAR files have a different structure to Jar files.
无法从 WAR 文件运行 java 类。WAR 文件与 Jar 文件具有不同的结构。
To find the related java classes, export (preferred way to use ant) them as Jar put it in your web app lib.
要查找相关的 Java 类,请导出(使用 ant 的首选方式)它们,因为 Jar 将其放入您的 Web 应用程序库中。
Then you can use the jar file as normal to run java program. The same jar was also referred in web app (if you put this jar in web app lib)
然后就可以正常使用jar文件运行java程序了。在 web app 中也引用了同一个 jar(如果你把这个 jar 放在 web app lib 中)
回答by Bojan Petkovic
Similar to what Richard Detsch but with a bit easier to follow (works with packages as well)
类似于 Richard Detsch,但更容易理解(也适用于包)
Step 1: Unwrap the War file.
第 1 步:解开 War 文件。
jar -xvf MyWar.war
Step 2: move into the directory
第二步:进入目录
cd WEB-INF
Step 3: Run your main with all dependendecies
第 3 步:运行包含所有依赖项的 main
java -classpath "lib/*:classes/." my.packages.destination.FileToRun
回答by Anthony O.
If you're using Maven, just follow the maven-war-plugin
documentation about "How do I create a JAR containing the classes in my webapp?": add <attachClasses>true</attachClasses>
to the <configuration>
of the plugin:
如果您使用的是 Maven,只需遵循maven-war-plugin
有关“如何在我的 web 应用程序中创建包含类的 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>
The you will have 2 products in the target/
folder:
您将在target/
文件夹中有 2 个产品:
- The
project.war
itself - The
project-classes.jar
which contains all the compiled classes in a jar
- 在
project.war
自身 - 该
project-classes.jar
包含在一个罐子里所有的编译的类
Then you will be able to execute a main class using classic method: java -cp target/project-classes.jar 'com.mycompany.MainClass' param1 param2
然后您将能够使用经典方法执行主类: java -cp target/project-classes.jar 'com.mycompany.MainClass' param1 param2
回答by Rick
the best way if you use Spring Boot is :
如果您使用 Spring Boot,最好的方法是:
1/ Create a ServletInitializer extends SpringBootServletInitializerClass . With method configurewhich run your Application Class
1/ 创建一个 ServletInitializer 扩展SpringBootServletInitializer类。使用方法配置运行您的应用程序类
2/ Generate alwaysa maven install WARfile
2/总是生成一个 maven 安装WAR文件
3/ With this artefact you can even :
3/ 有了这个人工制品,您甚至可以:
. start application from war file with java -jar file.war
. put your war file in your favorite Web App server (like tomcat, ...)