SimonA
SimonA

Reputation: 135

Added Gradle to Java project "Exception ... java.lang.NoClassDefFoundError"

I had an existing project without Gradle and needed to add com.google.code.gson:gson:+ library to work with JSON objects. To begin with I ran either gradle init or gradle build, I'm not sure. This caused my java classes with a main() not to run as the source path was wrong/changed. I have changed the structure following advice to at least get the classes to compile and run, but I still have this warning in run configurations "Warning: Class 'Main' not found in module 'src'" ;

enter image description here

If I set Use classpath of module to src.main, the warning goes away but when I run Main.main() Gradle seems to execute Gradle tasks, like this - this will run indefinitely;

enter image description here

Here is my project structure;

enter image description here

This is my build.gradle file;

 /*
 * This file was generated by the Gradle 'init' task.
 *
 * This generated file contains a sample Java project to get you started.
 * For more details take a look at the Java Quickstart chapter in the Gradle
 * User Manual available at https://docs.gradle.org/6.3/userguide/tutorial_java_projects.html
 */

plugins {
    // Apply the java plugin to add support for Java
    id 'java'

    // Apply the application plugin to add support for building a CLI application.
    id 'application'

    // idea plugin? // I added this to original build.gradle file
    id 'idea'
}

repositories {
    // Use jcenter for resolving dependencies.
    // You can declare any Maven/Ivy/file repository here.
    jcenter()
    mavenCentral()
    google()
}

dependencies {
    // This dependency is used by the application.
    implementation 'com.google.guava:guava:28.2-jre'

    // Use JUnit test framework
    testImplementation 'junit:junit:4.12'

    // For use with JSONUtil class // I added this to original build.gradle file
    compile 'com.google.code.gson:gson:+'
}

application {
    // Define the main class for the application.
    mainClassName = 'java.Main' // changed to 'Main' and I can `gradle run` seems to actually run Main.java
}

I have imported com.google.gson.JsonObject and com.google.gson.JsonParser from com.google.gson:gson:2.8.6 library, with no code inspection warnings, i.e available at compile time. If I run my code with a JsonObject jsonObject = new JsonObject I get the error;

Exception in thread "main" java.lang.NoClassDefFoundError: com/google/gson/JsonParser
    at HttpUtils.getAccessToken(HttpUtils.java:80)
    at Main.auth(Main.java:75)
    at Main.play(Main.java:36)
    at Main.main(Main.java:17)
Caused by: java.lang.ClassNotFoundException: com.google.gson.JsonParser
    at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:602)
    at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:178)
    at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:521)
    ... 4 more

Line 80 of HttpUtils.java;

JsonObject jsonResponse = JsonParser.parseString(response.body()).getAsJsonObject(); // todo: status 200 "success" else failed
            accessToken = jsonResponse.get("access_token").getAsString();
            System.out.println(accessToken);

I understand this means that JVM can't compile a .class for JsonParser? I suppose this means the compiler has no knowledge of the library existing, which makes me suspect that Gradle isn't configured properly with the project, as it has downloaded the library, but not added a path to it?

I have tried gradle cleanIdea and then gradle idea. I have rebuilt the the project. I have "Mark directory as source root" on various directories for testing being careful to revert when it failed to change behaviour.

Edit;

I have added a package com.example in the src.main.Java directory and added the java files.

enter image description here

I edited run configuration for Main.java to

I also changed the build.gradle file to;

application {
    // Define the main class for the application.
    mainClassName = 'com.example.Main'
}

Main runs but I am stuck at this point, which seems to run indefinitely;

enter image description here

Also, I am sure I right clicked on build.gradle and selected import, although I can't recreate this as the option isn't available now.

Edit 2;

I have been able to get the classes Main and Test with main() to run by putting them in the test/java/src package, and using unusual run configuration with warnings. Although on closer inspection, it seems to be running code that is previously compiled somewhere, as any changes I make aren't reflected in output.

Here is my project structure at the moment; enter image description here

This is my run configuration that actually runs main in the standard output console, rather than a Gradle Task. It's clearly wrong, as Main is not in the com.example package or src.main module. If I set it correctly using module src.test and main class src.Main Gradle runs as screenshot 5.

enter image description here

Edit 3;

I see now that Gradle has took over responsibility to build and run the java files. I didn't know running in the output could be done with another CLI app and I admit it confused me, so please forgive anything above that seems stupid, I'm learning and figuring this out as I go.

I found in InteliJ settings Build, Execution, Deployment > Build Tools > Gradle I can change the Build and run using option between InteliJ IDEA and Gradle. The only issue I'm having with Gradle now I understand what is happening is Gradle doesn't seem to update my .class files when I run my main() with Gradle. Maybe this is for another question though.

Upvotes: 0

Views: 441

Answers (1)

Andrey
Andrey

Reputation: 16381

mainClassName = 'java.Main' // changed to 'Main' and I can "gradle run" seems to actually run Main.java

This is not correct. Based on screenshot - you have not package named java (also I doubld that this is a valid name for a Java package). Create proper package inside src/main/java directory and specify it in the Main source file and in build.gradle file.

Also make sure you have imported build.gradle file in IDE, see Link a Gradle project to an IntelliJ IDEA project

Upvotes: 1

Related Questions