Gradle 2.1: no main manifest attribute

Trying to get a BASIC test that Gradle works properly in my environment. Some lines in directory list removed for clarity purposes. However, I have been through the documentation and Gradle produces a jar file, I cannot run the jar file. What am I missing?

C:\Code\gradletest>dir

Directory of C:\Code\gradletest

09/09/2014 09:21 AM

438 build.gradle 09/09/2014 09:41 AM

847 gradle-app.setting 09/09/2014 08:22 AM

126 HelloWorld.java 09/09/2014 09:19 AM

META-INF

Contents of build.gradle file is:

apply plugin: ‘java’ //apply plugin: ‘eclipse’

// tag::repositories[] repositories {

mavenCentral() } // end::repositories[]

// tag::jar[] jar {

baseName = ‘helloworld’

version = ‘0.1’ } // end::jar[]

// tag::dependencies[] dependencies {

compile “joda-time:joda-time:2.2” } // end::dependencies[]

// tag::wrapper[] task wrapper(type: Wrapper) {

gradleVersion = ‘2.1’ } // end::wrapper[]

Contents of META-INF\MANIFEST.MF

Manifest-Version: 1.0 Created-By: 1.8.0-b132 (Oracle Corporation) Main-Class: Code.gradletest.HelloWorld

Contents of HelloWorld.java

public class HelloWorld {

public static void main(String[] args) {

System.out.println(“Hello, world!”);

} }

First I used:

C:\Code\gradletest>gradle clean :clean

BUILD SUCCESSFUL

Total time: 4.824 secs

Then I used:

C:\Code\gradletest>gradle build :compileJava UP-TO-DATE :processResources UP-TO-DATE :classes UP-TO-DATE :jar :assemble :compileTestJava UP-TO-DATE :processTestResources UP-TO-DATE :testClasses UP-TO-DATE :test UP-TO-DATE :check UP-TO-DATE :build

BUILD SUCCESSFUL

Total time: 3.607 secs

C:\Code\gradletest>cd build\libs

C:\Code\gradletest\build\libs>dir

Directory of C:\Code\gradletest\build\libs

09/09/2014 09:23 AM

. 09/09/2014 09:23 AM

… 09/09/2014 09:23 AM

261 helloworld-0.1.jar

1 File(s)

261 bytes

2 Dir(s) 113,000,513,536 bytes free

Then I tried to run the jar and I consistently get the “error message”.

C:\Code\gradletest\build\libs>java -jar helloworld-0.1.jar no main manifest attribute, in helloworld-0.1.jar

I think you should use the “application” plugin, which provides a “mainClassName” project property. Read the user guide section on this plugin for more information.

the file build.gradle changed to:

apply plugin: ‘java’ apply plugin: ‘application’ //apply plugin: ‘eclipse’

// tag::repositories[] repositories {

mavenCentral() } …

and saved

gradle clean followed by gradle build results in:

C:\Code\gradletest>gradle clean :clean

BUILD SUCCESSFUL

Total time: 3.584 secs C:\Code\gradletest>gradle build :compileJava UP-TO-DATE :processResources UP-TO-DATE :classes UP-TO-DATE :jar :assemble :compileTestJava UP-TO-DATE :processTestResources UP-TO-DATE :testClasses UP-TO-DATE :test UP-TO-DATE :check UP-TO-DATE :build

BUILD SUCCESSFUL

Total time: 3.869 secs C:\Code\gradletest>

AND the MANIFEST.MF file reads as: Manifest-Version: 1.0 Created-By: 1.8.0-b132 (Oracle Corporation) Main-Class: Code.gradletest.HelloWorld

STILL unable to RUN the application. C:\Code\gradletest\build\libs>java -jar helloworld-0.1.jar

no main manifest attribute, in helloworld-0.1.jar

You appear to have “HelloWorld.java” in the root of your project. The Java plugin expects Java code in “src/main/java”, and the classes should match the package structure (Code/gradletest/HelloWorld.java). Did you ever inspect the actual contents of the jar file to see what’s in it?

I viewed the contents ( jar tf ) however I did not notice this. Let me try that. I will keep you posted. Thanks

C:\Code\gradletest>dir /s

Volume in drive C is Local Disk

Volume Serial Number is 383E-B55F

Directory of C:\Code\gradletest

09/10/2014 09:03 AM

. 09/10/2014 09:03 AM

… 09/10/2014 08:46 AM

525 build.gradle 09/10/2014 09:04 AM

META-INF 09/10/2014 08:34 AM

src

1 File(s)

525 bytes

Directory of C:\Code\gradletest\META-INF

09/10/2014 09:04 AM

. 09/10/2014 09:04 AM

… 09/10/2014 09:04 AM

110 MANIFEST.MF

1 File(s)

110 bytes

Directory of C:\Code\gradletest\src

09/10/2014 08:34 AM

. 09/10/2014 08:34 AM

… 09/10/2014 08:34 AM

main

0 File(s)

0 bytes

Directory of C:\Code\gradletest\src\main

09/10/2014 08:34 AM

. 09/10/2014 08:34 AM

… 09/10/2014 08:41 AM

java

0 File(s)

0 bytes

Directory of C:\Code\gradletest\src\main\java

09/10/2014 08:41 AM

. 09/10/2014 08:41 AM

… 09/10/2014 08:41 AM

code

0 File(s)

0 bytes

Directory of C:\Code\gradletest\src\main\java\code

09/10/2014 08:41 AM

. 09/10/2014 08:41 AM

… 09/10/2014 08:41 AM

gradletest

0 File(s)

0 bytes

Directory of C:\Code\gradletest\src\main\java\code\gradletest

09/10/2014 08:41 AM

. 09/10/2014 08:41 AM

… 09/09/2014 01:30 PM

126 HelloWorld.java

1 File(s)

126 bytes

Total Files Listed:

3 File(s)

761 bytes

20 Dir(s) 102,893,006,848 bytes free

C:\Code\gradletest>

Your package is “Code.gradletest”, but you’ve stored the source file in “code/gradletest”. DOS is case-insensitive, but Java is not.

OK deleted the whole directory structure and started again. Directory now looks like: C:\Code\gradletest>dir /s

Volume in drive C is Local Disk

Volume Serial Number is 383E-B55F

Directory of C:\Code\gradletest

09/10/2014 10:40 AM

. 09/10/2014 10:40 AM

… 09/10/2014 08:46 AM

525 build.gradle 09/10/2014 09:04 AM

META-INF 09/10/2014 08:34 AM

src

1 File(s)

525 bytes

Directory of C:\Code\gradletest\META-INF

09/10/2014 09:04 AM

. 09/10/2014 09:04 AM

… 09/10/2014 09:04 AM

110 MANIFEST.MF

1 File(s)

110 bytes

Directory of C:\Code\gradletest\src

09/10/2014 08:34 AM

. 09/10/2014 08:34 AM

… 09/10/2014 08:34 AM

main

0 File(s)

0 bytes

Directory of C:\Code\gradletest\src\main

09/10/2014 08:34 AM

. 09/10/2014 08:34 AM

… 09/10/2014 10:24 AM

java

0 File(s)

0 bytes

Directory of C:\Code\gradletest\src\main\java

09/10/2014 10:24 AM

. 09/10/2014 10:24 AM

… 09/10/2014 08:41 AM

Code

0 File(s)

0 bytes

Directory of C:\Code\gradletest\src\main\java\Code

09/10/2014 08:41 AM

. 09/10/2014 08:41 AM

… 09/10/2014 08:41 AM

gradletest

0 File(s)

0 bytes

Directory of C:\Code\gradletest\src\main\java\Code\gradletest

09/10/2014 08:41 AM

. 09/10/2014 08:41 AM

… 09/09/2014 01:30 PM

126 HelloWorld.java

1 File(s)

126 bytes

C:\Code\gradletest>gradle clean :clean UP-TO-DATE

BUILD SUCCESSFUL

Total time: 3.599 secs C:\Code\gradletest>gradle build :compileJava :processResources UP-TO-DATE :classes :jar :assemble :compileTestJava UP-TO-DATE :processTestResources UP-TO-DATE :testClasses UP-TO-DATE :test UP-TO-DATE :check UP-TO-DATE :build

BUILD SUCCESSFUL

Total time: 4.629 secs

C:\Code>cd gradletest

C:\Code\gradletest>cd build

C:\Code\gradletest\build>cd libs

C:\Code\gradletest\build\libs>dir

Volume in drive C is Local Disk

Volume Serial Number is 383E-B55F

Directory of C:\Code\gradletest\build\libs

09/10/2014 10:44 AM

. 09/10/2014 10:44 AM

… 09/10/2014 10:44 AM

702 helloworld-0.1.jar

1 File(s)

702 bytes

2 Dir(s) 102,894,796,800 bytes free

C:\Code\gradletest\build\libs>java -jar helloworld-0.1.jar no main manifest attribute, in helloworld-0.1.jar

OK David, I’ve rebuilt the directories.

I’ve written the Java code.

I’ve run gradle clean and gradle build.

I’ve put a MANIFEST.MF file in the META-INF directory.

Gradle appears to be installed properly. A jar file is produced.

I have tried to run it with gradle run and with the jar command. I still get: no main manifest attribute, in helloworld-0.1.jar

So I have updated the MANIFEST.MF in the jar with the MANIFEST.MF in the \build\libs directory. Used the jar uf to update the jar. Then ran java -jar command to get the same results.

What am I overlooking?

This MANIFEST.MF file that you’ve created is irrelevant. Gradle doesn’t use it. Wasn’t that clear from my earlier comments?

What do you mean by “I’ve written the Java code”?

Why don’t you show us your current build script, full text of your Java class, full directory structure, and full directory structure of the resulting jar?

OK the current build script is:

apply plugin: ‘java’ apply plugin: ‘application’

mainClassName = ‘Code.gradletest.HelloWorld’

// tag::repositories[] repositories {

mavenCentral() } // end::repositories[]

// tag::jar[] jar {

baseName = ‘helloworld’

version = ‘0.1’ } // end::jar[]

// tag::dependencies[] dependencies {

testCompile ‘junit:junit:4.8.2’

compile “joda-time:joda-time:2.2” } // end::dependencies[]

// tag::wrapper[] task wrapper(type: Wrapper) {

gradleVersion = ‘2.1’ } // end::wrapper[]

The java class:

public class HelloWorld {

public static void main(String[] args) {

System.out.println(“Hello, world!”);

} }

and is located at: C:\Code\gradletest\src\main\java\Code\gradletest

The full directory structure (with the META-INF removed) C:\Code>cd gradletest

C:\Code\gradletest>dir /s

Volume in drive C is Local Disk

Volume Serial Number is 383E-B55F

Directory of C:\Code\gradletest

09/10/2014 12:04 PM

. 09/10/2014 12:04 PM

… 09/10/2014 08:46 AM

525 build.gradle 09/10/2014 08:34 AM

src

1 File(s)

525 bytes

Directory of C:\Code\gradletest\src

09/10/2014 08:34 AM

. 09/10/2014 08:34 AM

… 09/10/2014 08:34 AM

main

0 File(s)

0 bytes

Directory of C:\Code\gradletest\src\main

09/10/2014 08:34 AM

. 09/10/2014 08:34 AM

… 09/10/2014 10:24 AM

java

0 File(s)

0 bytes

Directory of C:\Code\gradletest\src\main\java

09/10/2014 10:24 AM

. 09/10/2014 10:24 AM

… 09/10/2014 08:41 AM

Code

0 File(s)

0 bytes

Directory of C:\Code\gradletest\src\main\java\Code

09/10/2014 08:41 AM

. 09/10/2014 08:41 AM

… 09/10/2014 08:41 AM

gradletest

0 File(s)

0 bytes

Directory of C:\Code\gradletest\src\main\java\Code\gradletest

09/10/2014 08:41 AM

. 09/10/2014 08:41 AM

… 09/09/2014 01:30 PM

126 HelloWorld.java

1 File(s)

126 bytes

Total Files Listed:

2 File(s)

651 bytes

17 Dir(s) 102,882,689,024 bytes free

C:\Code\gradletest>

C:\Code\gradletest>gradle clean :clean UP-TO-DATE

BUILD SUCCESSFUL

Total time: 3.597 secs C:\Code\gradletest>gradle build :compileJava :processResources UP-TO-DATE :classes :jar :assemble :compileTestJava UP-TO-DATE :processTestResources UP-TO-DATE :testClasses UP-TO-DATE :test UP-TO-DATE :check UP-TO-DATE :build

BUILD SUCCESSFUL

Total time: 4.703 secs C:\Code\gradletest>

the directory structure AFTER the build

C:\Code\gradletest>dir /s

Volume in drive C is Local Disk

Volume Serial Number is 383E-B55F

Directory of C:\Code\gradletest

09/10/2014 12:06 PM

. 09/10/2014 12:06 PM

… 09/10/2014 12:06 PM

.gradle 09/10/2014 12:06 PM

build 09/10/2014 08:46 AM

525 build.gradle 09/10/2014 08:34 AM

src

1 File(s)

525 bytes

Directory of C:\Code\gradletest.gradle

09/10/2014 12:06 PM

. 09/10/2014 12:06 PM

… 09/10/2014 12:06 PM

2.1

0 File(s)

0 bytes

Directory of C:\Code\gradletest.gradle\2.1

09/10/2014 12:06 PM

. 09/10/2014 12:06 PM

… 09/10/2014 12:06 PM

taskArtifacts

0 File(s)

0 bytes

Directory of C:\Code\gradletest.gradle\2.1\taskArtifacts

09/10/2014 12:06 PM

. 09/10/2014 12:06 PM

… 09/10/2014 12:06 PM

31 cache.properties 09/10/2014 12:06 PM

17 cache.properties.lock 09/10/2014 12:06 PM

18,790 fileHashes.bin 09/10/2014 12:06 PM

19,282 fileSnapshots.bin 09/10/2014 12:06 PM

18,602 outputFileStates.bin 09/10/2014 12:06 PM

19,542 taskArtifacts.bin

6 File(s)

76,264 bytes

Directory of C:\Code\gradletest\build

09/10/2014 12:06 PM

. 09/10/2014 12:06 PM

… 09/10/2014 12:06 PM

classes 09/10/2014 12:06 PM

dependency-cache 09/10/2014 12:06 PM

libs 09/10/2014 12:06 PM

tmp

0 File(s)

0 bytes

Directory of C:\Code\gradletest\build\classes

09/10/2014 12:06 PM

. 09/10/2014 12:06 PM

… 09/10/2014 12:06 PM

main

0 File(s)

0 bytes

Directory of C:\Code\gradletest\build\classes\main

09/10/2014 12:06 PM

. 09/10/2014 12:06 PM

… 09/10/2014 12:06 PM

535 HelloWorld.class

1 File(s)

535 bytes

Directory of C:\Code\gradletest\build\dependency-cache

09/10/2014 12:06 PM

. 09/10/2014 12:06 PM

0 File(s)

0 bytes

Directory of C:\Code\gradletest\build\libs

09/10/2014 12:06 PM

. 09/10/2014 12:06 PM

… 09/10/2014 12:06 PM

702 helloworld-0.1.jar

1 File(s)

702 bytes

Directory of C:\Code\gradletest\build\tmp

09/10/2014 12:06 PM

. 09/10/2014 12:06 PM

… 09/10/2014 12:06 PM

compileJava 09/10/2014 12:06 PM

jar

0 File(s)

0 bytes

Directory of C:\Code\gradletest\build\tmp\compileJava

09/10/2014 12:06 PM

. 09/10/2014 12:06 PM

0 File(s)

0 bytes

Directory of C:\Code\gradletest\build\tmp\jar

09/10/2014 12:06 PM

. 09/10/2014 12:06 PM

… 09/10/2014 12:06 PM

25 MANIFEST.MF

1 File(s)

25 bytes

Directory of C:\Code\gradletest\src

09/10/2014 08:34 AM

. 09/10/2014 08:34 AM

… 09/10/2014 08:34 AM

main

0 File(s)

0 bytes

Directory of C:\Code\gradletest\src\main

09/10/2014 08:34 AM

. 09/10/2014 08:34 AM

… 09/10/2014 10:24 AM

java

0 File(s)

0 bytes

Directory of C:\Code\gradletest\src\main\java

09/10/2014 10:24 AM

. 09/10/2014 10:24 AM

… 09/10/2014 08:41 AM

Code

0 File(s)

0 bytes

Directory of C:\Code\gradletest\src\main\java\Code

09/10/2014 08:41 AM

. 09/10/2014 08:41 AM

… 09/10/2014 08:41 AM

gradletest

0 File(s)

0 bytes

Directory of C:\Code\gradletest\src\main\java\Code\gradletest

09/10/2014 08:41 AM

. 09/10/2014 08:41 AM

… 09/09/2014 01:30 PM

126 HelloWorld.java

1 File(s)

126 bytes

Total Files Listed:

11 File(s)

78,177 bytes

50 Dir(s) 102,881,136,640 bytes free

Now you’ve changed your Java class so it’s now in the default package, instead of “Code.gradletest”, but all of the other references expect it to be in “Code.gradletest”. The package the class is defined to be in has to match the folder structure the source file resides in.

Add back the following statement to the top of your class:

package Code.gradletest;

And when you’re asked to provide additional information, there’s not much point in creating separate responses for each piece of information.

It looks to me like you need to learn some basic principles of Java.

HelloWorld.java now reads: ( Located at C:\Code\gradletest\src\main\java\Code\gradletest )

package Code.gradletest;

public class HelloWorld {

public static void main(String[] args) {

System.out.println(“Hello, world!”);

} }

then I:

C:\Code\gradletest>gradle clean :clean

BUILD SUCCESSFUL

Total time: 3.599 secs C:\Code\gradletest>gradle build :compileJava :processResources UP-TO-DATE :classes :jar :assemble :compileTestJava UP-TO-DATE :processTestResources UP-TO-DATE :testClasses UP-TO-DATE :test UP-TO-DATE :check UP-TO-DATE :build

BUILD SUCCESSFUL

Total time: 4.77 secs C:\Code\gradletest>

Learning is what I am trying to do. I realize it must be frustrating dealing with a problem like this. Thank you for your effort.

C:\Code\gradletest>cd build

C:\Code\gradletest\build>cd libs

C:\Code\gradletest\build\libs>dir

Volume in drive C is Local Disk

Volume Serial Number is 383E-B55F

Directory of C:\Code\gradletest\build\libs

09/10/2014 12:27 PM

. 09/10/2014 12:27 PM

… 09/10/2014 12:27 PM

946 helloworld-0.1.jar

1 File(s)

946 bytes

2 Dir(s) 102,874,337,280 bytes free

C:\Code\gradletest\build\libs>java -jar helloworld-0.1.jar no main manifest attribute, in helloworld-0.1.jar

C:\Code\gradletest\build\libs>

I still get the error. The META-INF has been removed.

jar tf helloworld-0.1.jar shows:

C:\Code\gradletest\build\libs>java -jar helloworld-0.1.jar no main manifest attribute, in helloworld-0.1.jar

C:\Code\gradletest\build\libs>jar tf helloworld-0.1.jar META-INF/ META-INF/MANIFEST.MF Code/ Code/gradletest/ Code/gradletest/HelloWorld.class

C:\Code\gradletest\build\libs>jar xf helloworld-0.1.jar shows that the MANIFEST.MF file has only 2 lines (1 blank line) Manifest-Version: 1.0

Interesting. It appears that adding “mainClassName” has no effect on the manifest. However, if you do “gradle run” at this point, it should execute the main class.

If you also want the manifest change, then you’ll have to add something like the following to your build.gradle:

jar {
    manifest {
        attributes 'Main-Class': 'Code.gradletest.HelloWorld'
    }
}

With this, both “gradle run” and your “java -jar …” approach will execute the main class. It won’t matter for this simple test case, but what you will NOT get with the “java -jar” approach is any additional jars in the classpath needed by a more complex main class. This is something that “gradle run” does take care of for you. I would imagine there are ways to amend the manifest with “classpath” properties that add your dependencies.

Thank you for all your help.