21

I recently just started toying around with Maven in java. Time comes to test my project, it works fine in the NetBeans window, running the main class found in App.java (com.MyCompany.App), but when I try to run it from a command line I get an error:

java -jar fileName.jar

"No Main Manifest Attribute" in fileName.jar

I have tried adding a manifest.mf file specifying what main is, I've also been into project properties and added it as the main file...

What's going on?

ROMANIA_engineer
  • 54,432
  • 29
  • 203
  • 199
A_Elric
  • 3,508
  • 13
  • 52
  • 85

6 Answers6

19

You need the maven-jar-plugin (see Maven's example). This plugin will create the required entries in the manifest file when the project is built.

<project>
  ...
  <build>
    <plugins>
      ...
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-jar-plugin</artifactId>
        <version>2.3.2</version>
        <configuration>
          <archive>
            <manifest>
              <addClasspath>true</addClasspath>
              <mainClass>fully.qualified.MainClass</mainClass>
            </manifest>
          </archive>
        </configuration>
      </plugin>
      ...
    </plugins>
  </build>
  ...
</project>

You need the version, otherwise, the project won't build. The fully.qualified.MainClass starts at the package hierarchy.

yshehab
  • 352
  • 3
  • 7
10

Hope there is a problem in your manifest file. Some basic checks might solve your problem.

  • it should under /META-INF/MANIFEST.MF
  • Content should have Main-Class:com.MyCompany.App

If you are using any IDE, there should be an option to export project as runnable jar, you can make use of that to let the IDE take care of correct manifest.

From command line jar cfm filename.jar Manifest.txt com/MyCompany/*.class which generates the Manifest file with following contents

Manifest-Version: 1.0
Created-By: 1.6.0 (Sun Microsystems Inc.)
Main-Class: com.MyCompany.App

And then you can run jar command java -jar fileName.jar.

These type of problems are trivial but kills lot of time, just ensure your contents and location of the file is correct.

RP-
  • 5,827
  • 2
  • 27
  • 46
  • 1
    I gave this a shot, trying java jar cfm testSql-1.0.jar Manifest.txt com/MyCompany/testsql/*.class and it returned the error "Could not find or load main class jar" – A_Elric Sep 04 '12 at 16:00
  • Do you have an empty line at the end of the manifest file? Last line wont be parsed in a manifest file. – RP- Sep 04 '12 at 16:04
  • My manifest shows like this: Manifest-Version: 1.0 Archiver-Version: Plexus Archiver Created-By: Apache Maven Built-By: dbell Build-Jdk: 1.7.0_05 It's being generated by the IDE though – A_Elric Sep 04 '12 at 16:05
  • It seems this is not a `runnable jar` as you don't have `Main-Class` attribute. You can try `jar cfe filename.jar com.MyComapany.App com/MyCompany/App.class` – RP- Sep 04 '12 at 16:10
  • 5
    In Netbeans, Run->Project Configuration->Customize->Run->Main Class->Browse and select you main class. Then re-build. – Pete Jul 08 '13 at 12:03
  • 1
    @Pete this doesn't work with Maven projects in NetBeans. It only works for projects managed by npproject – KFL May 08 '14 at 19:56
4

You could just use this for command line:

java -cp jarFileName.jar full.package.className

You wouldn't have to go into specifics of the Manifest file in this case.

kenorb
  • 155,785
  • 88
  • 678
  • 743
rachel
  • 41
  • 2
  • 1
    While yours is a valid option, it doesn't exactly answer the "what's going on?" part of the question. – adamdunson Mar 06 '13 at 18:19
  • @adamdunson "What's going on" is directly related to which IDE is involved. For NetBeans specifically, Nate has posted the correct solution above. – fIwJlxSzApHEZIl Apr 02 '14 at 03:43
1

Setting an Entry Point with the JAR Tool:

The 'e' flag (for 'entrypoint') creates or overrides the manifest's Main-Class attribute. It can be used while creating or updating a JAR file. Use it to specify the application entry point without editing or creating the manifest file. For example, this command creates app.jar where the Main-Class attribute value in the manifest is set to MyApp:

jar cfe app.jar MyApp MyApp.class

You can directly invoke this application by running the following command:

java -jar app.jar

If the entrypoint class name is in a package it may use a '.' (dot) character as the delimiter. For example, if Main.class is in a package called foo the entry point can be specified in the following ways:

jar cfe Main.jar foo.Main foo/Main.class
1

If you look at the properties dialog for the project (from project tab, right click on your project and select properties) you'll see that there is a "run" item in the "Categories" window. Click on it and you'll see a dialog where you can specify the Main Class for the jar. That information will end up in your manifest.

0

I have been having this problem with Netbeans 8.0 and the built-in Maven project for the "Java Application" project prototype. Also I have Maven 3 and I found some of the suggestions on the web don't match the maven code used with Netbeans as well.

Anyway here's a simple recipe for having JAR file to run the main-class and embed dependent libraries. I made this work by comparing other project POM files for projects I found that worked with sub-project JAR-s so if someone with better Maven knowledge spots a gottcha, please speak. Also, I left in some normal stuff to provide context. Example follows:

     <properties>
         <packageName>trials.example</packageName>
         <mainClass>${packageName}.CmdApp</mainClass>
         <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>

         <slf4jVersion>1.7.7</slf4jVersion>
         <log4jVersion>1.2.17</log4jVersion>

         <maven.compiler.source>1.8</maven.compiler.source>
         <maven.compiler.target>1.8</maven.compiler.target>
     </properties>

This section tells Maven about the project.

  • packageName ... Is the Java package for the main-class
  • mainClass ..... The fully qualified name for class with main() method.

You will see these used in the maven-jar-plugin.

The other thing the built-in example prototype didn't do was to package my sub-projects into the JAR so I can run from the command line. This is done with the maven-dependency-plugin below. The interesting bit is in the where we don't need to package the system stuff, and we want the dependant classes wrapped into our JAR.

These are used as follows:

     <build>
         <plugins>
             <plugin>
                 <groupId>org.apache.maven.plugins</groupId>
                 <artifactId>maven-dependency-plugin</artifactId>
                 <version>2.6</version>
                 <executions>
                     <execution>
                         <id>unpack-dependencies</id>
                         <phase>package</phase>
                         <goals>
                             <goal>unpack-dependencies</goal>
                         </goals>
                         <configuration>
                             <excludeScope>system</excludeScope>
                             <outputDirectory>${project.build.directory}/classes</outputDirectory>
                         </configuration>
                     </execution>
                 </executions>
             </plugin>

             <plugin>
                 <groupId>org.apache.maven.plugins</groupId>
                 <artifactId>maven-jar-plugin</artifactId>
                 <version>2.5</version>
                 <configuration>
                     <useDefaultManifestFile>true</useDefaultManifestFile>
                     <archive>
                         <manifest>
                             <mainClass>${mainClass}</mainClass>
                             <packageName>${packageName}</packageName>
                             <addClasspath>true</addClasspath>
                             <classpathPrefix>classes/</classpathPrefix>
                         </manifest>
                         <manifestEntries>
                            <mode>development</mode>
                            <url>${pom.url}</url>
                         </manifestEntries>
                     </archive>
                 </configuration>
             </plugin>

          </plugins>
    </build>

Hope that saves you the few hours of checking and testing to make it happen. Cheers, Will.

will
  • 4,799
  • 8
  • 54
  • 90
  • could you please update this answer? The maven jar plugin has changed.. – Human Nov 29 '19 at 16:59
  • @Human ... Thanks that's a good point! The best thing is for YOU readers there, check these points (above) with the latest documentation. Our projects use Gradle now days and I'm not in the loop. Happy to ppoint to a correction if someone wants to post as an Answer here. – will Dec 04 '19 at 22:42