如何从命令行在WAR中运行类?

Sim*_*mon 66 java jar war

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

java -jar myjar.jar params
Run Code Online (Sandbox Code Playgroud)

我需要重新打包代码以在apache下运行,我的所有代码(包括旧jar中的入口点类)最终都在WAR文件中,以便轻松地进入Web服务器.

但是,我仍然希望能够从命令行运行它并且代码没有改变并且全部在那里,我只是无法弄清楚如何让它运行.

这是我试过的......

我认为WAR就像一个罐子,所以

java -jar mywar.war params
Run Code Online (Sandbox Code Playgroud)

那失败了说清单中没有定义主类.

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

我注意到在我的战争中我有一个名为META-INF的文件夹,其中包含一个manifest.mf,所以我在声明我的主要类时添加了一行,因为我想要一个正常的清单...

Manifest-Version: 1.0
Main-Class: mypackage.MyEntryPointClass
Run Code Online (Sandbox Code Playgroud)

这给了一个noClassDefFoundError mypackage.MyEntryPointClass,这是一种进步.这让我相信这只是一个路径问题,所以我试过了

Manifest-Version: 1.0
Main-Class: WEB-INF.classes.mypackage.MyEntryPointClass
Run Code Online (Sandbox Code Playgroud)

我现在得到相同的错误,但有一个堆栈跟踪...

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)
Run Code Online (Sandbox Code Playgroud)

我已经google了一下,但找不到任何能回答我问题的内容,而且我在这里读了几个略有不同的问题,所以我想我会发帖.

Java 1.5,不是我认为应该有所作为.

Yon*_*man 37

你可以做Hudson(持续集成项目)所做的事情.你下载了一个可以在tomcat中部署或执行使用的战争

java -jar hudson.war
Run Code Online (Sandbox Code Playgroud)

(因为它有一个嵌入式Jetty引擎,从命令行运行它会导致服务器启动.)无论如何,通过查看hudson的清单,我知道他们将一个Main类放在根目录中.在您的情况下,您的战争布局应如下所示:

根下:

  • mypackage中/ MyEntryPointClass.class
  • WEB-INF/lib目录
  • WEB-INF/classes目录
  • META-INF/MANIFEST.MF

清单应包括以下行:

Main-Class: mypackage.MyEntryPointClass
Run Code Online (Sandbox Code Playgroud)

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

HTH

  • 不会投反对票,因为答案包含一些好的信息。但是,它没有回答原始问题“...作为独立应用程序从命令行运行...” (2认同)

Boj*_*vic 33

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

第1步:打开War文件.

jar -xvf MyWar.war
Run Code Online (Sandbox Code Playgroud)

第2步:进入目录

cd WEB-INF
Run Code Online (Sandbox Code Playgroud)

第3步:使用所有依赖项运行main

java -classpath "lib/*:classes/." my.packages.destination.FileToRun
Run Code Online (Sandbox Code Playgroud)

  • 对于Windows,请更改`:->;`,使上述命令成为`java -classpath“ lib / *; classes /”。my.packages.destination.FileToRun`特别更改 (2认同)

Boz*_*zho 10

战争是一个webapp.如果您希望控制台/独立应用程序重用与webapp相同的类,请考虑将您的共享类打包在jar中,您可以将其放入WEB-INF/lib.然后从命令行使用该jar.因此,您可以获得控制台应用程序,并且可以在servlet中使用相同的类,而无需创建两个不同的包.当然,这在战争爆发时也是如此.


Ric*_*sch 8

要从已部署的war文件执行SomeClass.main(String [] args),请执行以下操作:

第1步:编写具有主方法方法的类SomeClass.java即(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 :(查看类SomeOtherClass.class是否在/ usr/tomcat/webapps/projectName/WEB-INF/lib中)

run - > cd/usr/tomcat/webapps/projectName/WEB-INF/lib && find.-name'*.jar'| 读取jarfile; 如果jar tf"$ jarfile"| grep SomeOtherClass.class; 然后回显"$ jarfile"; 网络连接; DONE

注意2:写入标准输出,以便您可以通过打印语句查看主实际是否正常工作到控制台.这被称为后门.

注3:Bozhidar Bozhanov的上述评论似乎是正确的


Ant*_* O. 7

如果您使用的是 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>
Run Code Online (Sandbox Code Playgroud)

您将在target/文件夹中有 2 个产品:

  • project.war自身
  • project-classes.jar包含在一个罐子里所有的编译的类

然后您将能够使用经典方法执行主类: java -cp target/project-classes.jar 'com.mycompany.MainClass' param1 param2


Jas*_*man 6

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

您可以执行所要求的唯一方法是重新打包战争,以便.class文件驻留在mypackage归档根目录中的目录中,而不是WEB-INF/classes目录中.但是,如果这样做,您将无法再从任何Web类访问该文件.

如果你想在java命令行的war和outside中重用这个类,可以考虑构建一个可以从命令行运行的可执行jar,然后将该jar放在war文件的WEB-INF/lib目录中.


mar*_*osh 5

Maven项目中,您可以通过设置为.jar 使用Maven War 插件自动构建 jar 。下面举例。archiveClassestrue

<plugin>
       <groupId>org.apache.maven.plugins</groupId>
       <artifactId>maven-war-plugin</artifactId>
       <configuration>
        <archiveClasses>true</archiveClasses>
       </configuration>
</plugin>
Run Code Online (Sandbox Code Playgroud)