0

i'm beginner with Java and I got some troubles when I run my .jar. I got a ClassNotFoundException on a netty class. It seems logic that my .jar doesn't find the netty classes.

Here is my trace :

Exception in thread "main" java.lang.NoClassDefFoundError: io/netty/channel/EventLoopGroup
 at src.Main.main(Main.java:14)
Caused by: java.lang.ClassNotFoundException: io.netty.channel.EventLoopGroup
 at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(Unknown Source)
 at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(Unknown Source)
 at java.base/java.lang.ClassLoader.loadClass(Unknown Source)
 ... 1 more

The compilation works fine with gradle. My main build.gradle invokes 2 build.gradle in different folders that compile the program. Here is my main build.gradle :

subprojects {
        apply plugin: 'java'

        repositories {
                mavenCentral()
        }

        dependencies {
                compile 'io.netty:netty-all:4.1.16.Final'
                compile files("./lib/netty-all-4.1.16.Final.jar")
                testCompile 'junit:junit:4.12'
        }
}

And here is a build.gradle that is invoked by the main build.gradle, it compiles my sources.java :

apply plugin: "java"

sourceSets {
        main.java.srcDir "./src/"
}

jar {
        manifest.attributes "Main-Class": "src.Main"
        destinationDir project.file('../Jar/')
        baseName 'Server'
}

My file tree looks like this :

MyProject
--> build.gradle
--> settings.gradle
--> lib [DIR]
    --> netty-all-4.1.16.Final.jar
--> server [DIR]
    --> build.gradle
    --> src [DIR]
        --> Main.java

I don't understand why when I compile everything works, and when I run it doesn't find the netty classes.

Could you please help me ? Thank you !

Fake
  • 220
  • 1
  • 4
  • 11
  • How are you running your application? Are you using Gradle or are you invoking it directly? The exception indicates that Netty classes are not in your runtime classpath. – Oz. Oct 19 '17 at 13:01
  • Hi Oz, to compile I use 'gradle build', and to execute my .jar I use java -jar myjar.jar – Fake Oct 19 '17 at 13:08
  • You may look at this answer: https://stackoverflow.com/a/18413058/327680 – Oz. Oct 19 '17 at 13:29

2 Answers2

1

When you are running from command line, you are not adding the jars to the runtime classpath that were present on the compile time classpath.

It's probably easiest to create a runner task in Gradle as follows:

task runMyApp(type: JavaExec) {
    dependsOn 'classes'
    main = 'src.Main'
    classpath = sourceSets.main.runtimeClasspath
}

I suggest that you use the application plugin which will bundle your compiled jar into a zip (or tar) file alongside the dependency jars, it will also create a start script for windows and unix. It also adds an installDist task which deploys the application to run locally from command line.

Also, referencing local jars is a bad idea. If possible you should get your dependencies from a repository. Ie the following is bad

compile files("./lib/netty-all-4.1.16.Final.jar")
lance-java
  • 25,497
  • 4
  • 59
  • 101
0

Ok, I had a manifest into my build.gradle and now it works but i'm getting warning at runtime :

WARNING: An illegal reflective access operation has occurred
WARNING: Illegal reflective access by io.netty.util.internal.ReflectionUtil (file:/Users/AK1/Java/Java_jcoinche_2017/lib/netty-all-4.1.16.Final.jar) to constructor java.nio.DirectByteBuffer(long,int)
WARNING: Please consider reporting this to the maintainers of io.netty.util.internal.ReflectionUtil
WARNING: Use --illegal-access=warn to enable warnings of further illegal reflective access operations
WARNING: All illegal access operations will be denied in a future release

Here is my manifest added into my build.gradle file :

jar {
  manifest {
   attributes("Implementation-Title": "Server",
                 "Implementation-Version": "1.0",
   "Class-Path": "../lib/netty-all-4.1.16.Final.jar")
  }
 }

I think that what I've done is a bad practice. Is there a better way ?

Fake
  • 220
  • 1
  • 4
  • 11