How do I run a class in a WAR from the command line?

Solution 1:

Similar to what Richard Detsch but with a bit easier to follow (works with packages as well)

Step 1: Unwrap the War file.

jar -xvf MyWar.war

Step 2: move into the directory

cd WEB-INF

Step 3: Run your main with all dependendecies

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

Solution 2:

You can do what Hudson (continuous integration project) does. you download a war which can be deployed in tomcat or to execute using

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:

under root:

  • mypackage/MyEntryPointClass.class
  • WEB-INF/lib
  • WEB-INF/classes
  • META-INF/MANIFEST.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.

HTH

Solution 3:

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.

Solution 4:

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:

<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:

  • The project.war itself
  • The project-classes.jar which contains all the compiled classes in a 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

Solution 5:

To execute SomeClass.main(String [] args) from a deployed war file do:

  1. Write class SomeClass.java that has a main method method i.e. (public static void main(String[] args) {...})
  2. Deploy your 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

Note1: to see if the class SomeOtherClass.class is in /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 

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.

Note3: The comment above by Bozhidar Bozhanov seems correct