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

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

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

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

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.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)

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.

This question is related to java jar war

The answer is


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


It's not possible to run a java class from a WAR file. WAR files have a different structure to Jar files.

To find the related java classes, export (preferred way to use ant) them as Jar put it in your web app lib.

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)


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

the best way if you use Spring Boot is :

1/ Create a ServletInitializer extends SpringBootServletInitializer Class . With method configure which run your Application Class

2/ Generate always a maven install WAR file

3/ With this artefact you can even :

    . start application from war file with java -jar file.war

    . put your war file in your favorite Web App server (like tomcat, ...)

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


In Maven project, You can build jar automatically using Maven War plugin by setting archiveClasses to true. Example below.

<plugin>
       <groupId>org.apache.maven.plugins</groupId>
       <artifactId>maven-war-plugin</artifactId>
       <configuration>
        <archiveClasses>true</archiveClasses>
       </configuration>
</plugin>

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.


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

Step 1: Write class SomeClass.java that has a main method method i.e. (public static void main(String[] args) {...})

Step 2: Deploy your WAR

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

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


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.

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.

You can always just create two separate files.


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.

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.

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.


Examples related to java

Under what circumstances can I call findViewById with an Options Menu / Action Bar item? How much should a function trust another function How to implement a simple scenario the OO way Two constructors How do I get some variable from another class in Java? this in equals method How to split a string in two and store it in a field How to do perspective fixing? String index out of range: 4 My eclipse won't open, i download the bundle pack it keeps saying error log

Examples related to jar

Running JAR file on Windows 10 Add jars to a Spark Job - spark-submit Deploying Maven project throws java.util.zip.ZipException: invalid LOC header (bad signature) java.lang.NoClassDefFoundError: com/fasterxml/jackson/core/JsonFactory Maven Error: Could not find or load main class Where can I download mysql jdbc jar from? Access restriction: The type 'Application' is not API (restriction on required library rt.jar) Create aar file in Android Studio Checking Maven Version Creating runnable JAR with Gradle

Examples related to war

Deploying Java webapp to Tomcat 8 running in Docker container What is WEB-INF used for in a Java EE web application? How to unpackage and repackage a WAR file How to start jenkins on different port rather than 8080 using command prompt in Windows? Update Jenkins from a war file Oracle JDBC ojdbc6 Jar as a Maven Dependency UnsupportedClassVersionError unsupported major.minor version 51.0 unable to load class How to extract .war files in java? ZIP vs JAR How do I update a Tomcat webapp without restarting the entire service? Difference between jar and war in Java