I wrote my code following Netty’s documentation, then I execute:
mvn package
It builds successfully. Then I run:
java -jar target/netty-listener-0.0.1-SNAPSHOT.jar
And it promts me with this error:
Exception in thread “main” java.lang.NoClassDefFoundError: io/netty/channel/EventLoopGroup at java.lang.Class.getDeclaredMethods0(Native Method) at java.lang.Class.privateGetDeclaredMethods(Class.java:2701) at java.lang.Class.privateGetMethodRecursive(Class.java:3048) at java.lang.Class.getMethod0(Class.java:3018) at java.lang.Class.getMethod(Class.java:1784) at sun.launcher.LauncherHelper.validateMainClass(LauncherHelper.java:544) at sun.launcher.LauncherHelper.checkAndLoadMain(LauncherHelper.java:526) Caused by: java.lang.ClassNotFoundException: io.netty.channel.EventLoopGroup at java.net.URLClassLoader.findClass(URLClassLoader.java:381) at java.lang.ClassLoader.loadClass(ClassLoader.java:424) at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:331) at java.lang.ClassLoader.loadClass(ClassLoader.java:357) … 7 more
To my understanding, the JRE is not finding Netty’s EventLoopGroup Class in execution time. In Eclipse, I see the netty-all dependency on Maven’s dependency tab and EventLoopGroup is there. I’ve tried to change Netty’s version multiple times but it does not work.
Here is my main code:
package paplistener; import io.netty.bootstrap.ServerBootstrap; import io.netty.channel.ChannelFuture; import io.netty.channel.ChannelInitializer; import io.netty.channel.ChannelOption; import io.netty.channel.EventLoopGroup; import io.netty.channel.nio.NioEventLoopGroup; import io.netty.channel.socket.SocketChannel; import io.netty.channel.socket.nio.NioServerSocketChannel; public class PAPServer { private int port; public PAPServer(int port) { this.port = port; } public void run() throws Exception { EventLoopGroup bossGroup = new NioEventLoopGroup(); EventLoopGroup workerGroup = new NioEventLoopGroup(); try { ServerBootstrap b = new ServerBootstrap(); b.group(bossGroup, workerGroup) .channel(NioServerSocketChannel.class) .childHandler(new ChannelInitializer<SocketChannel>() { @Override public void initChannel(SocketChannel ch) throws Exception { ch.pipeline().addLast(new CommandDecoder(), new PAPServerHandler()); } }) .option(ChannelOption.SO_BACKLOG, 128) .childOption(ChannelOption.SO_KEEPALIVE, true); ChannelFuture f = b.bind(port).sync(); f.channel().closeFuture().sync(); } finally { workerGroup.shutdownGracefully(); bossGroup.shutdownGracefully(); } } public static void main(String[] args) throws Exception { int port = 8080; if(args.length > 0) { port = Integer.parseInt(args[0]); } new PAPServer(port).run(); } }
It is almost the exact code from Netty’s documentation, but it adds a decoder in the beginning of the pipeline.
Here is my pom.xml:
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>neurony.listener</groupId> <artifactId>netty-listener</artifactId> <version>0.0.1-SNAPSHOT</version> <packaging>jar</packaging> <dependencies> <dependency> <groupId>io.netty</groupId> <artifactId>netty-all</artifactId> <version>4.1.53.Final</version> <scope>compile</scope> </dependency> <dependency> <groupId>javassist</groupId> <artifactId>javassist</artifactId> <version>3.12.1.GA</version> </dependency> </dependencies> <build> <pluginManagement> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <version>3.1</version> <configuration> <source>1.8</source> <target>1.8</target> </configuration> </plugin> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-jar-plugin</artifactId> <version>2.4</version> <configuration> <archive> <manifest> <mainClass>paplistener.PAPServer</mainClass> </manifest> </archive> </configuration> </plugin> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-dependency-plugin</artifactId> <version>2.5.1</version> <executions> <execution> <id>copy-dependencies</id> <phase>package</phase> <goals> <goal>copy-dependencies</goal> </goals> <configuration> <outputDirectory> ${project.build.directory}/dependency-jars/ </outputDirectory> </configuration> </execution> </executions> </plugin> </plugins> </pluginManagement> </build> </project>
What can I do to solve this problem?
EDIT1: Added maven-shade-plugin to pom.xml but the (same) problem persists.
Lines added to pom:
<plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-shade-plugin</artifactId> <version>3.2.4</version> <executions> <execution> <phase>package</phase> <goals> <goal>shade</goal> </goals> <configuration> <transformers> <transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer"> <manifestEntries> <Main-Class>paplistener.PAPServer</Main-Class> <Build-Number>1</Build-Number> </manifestEntries> </transformer> </transformers> </configuration> </execution> </executions> </plugin>
EDIT2: added artifactSet to pom.xml but it didn’t work
<artifactSet> <includes> <include>io.netty:*</include> </includes> </artifactSet>
I tried * : * as well, just as Yuri G. suggested.
EDIT3: Contents of unzip -l:
Archive: netty-listener-0.0.1-SNAPSHOT.jar Length Date Time Name
0 10-29-2020 10:17 META-INF/ 266 10-29-2020 10:17 META-INF/MANIFEST.MF 0 10-29-2020 10:17 paplistener/ 2903 10-29-2020 10:17 paplistener/PAPCommandHandler.class 2554 10-29-2020 10:17 paplistener/PAPServer.class 2103 10-29-2020 10:17 paplistener/CommandDecoder.class 2834 10-29-2020 10:17 paplistener/PAPServerHandler.class 1319 10-29-2020 10:17 paplistener/PAPServer$1.class 0 10-29-2020 10:17 META-INF/maven/ 0 10-29-2020 10:17 META-INF/maven/neurony.listener/ 0 10-29-2020 10:17 META-INF/maven/neurony.listener/netty-listener/ 3572 10-28-2020 12:29 META-INF/maven/neurony.listener/netty-listener/pom.xml 125 10-29-2020 10:17 META-INF/maven/neurony.listener/netty-listener/pom.properties
15676 13 files
It seems like netty is not being copied to the jar file. But I still don’t know how to solve it. I’ll link here the generated .classpath (I guess Eclipse generated it):
<?xml version="1.0" encoding="UTF-8"?> <classpath> <classpathentry kind="src" path="src/test/java" output="target/test-classes" including="**/*.java"/> <classpathentry kind="src" path="src/test/resources" output="target/test-classes" excluding="**/*.java"/> <classpathentry kind="src" path="src/main/java" including="**/*.java"/> <classpathentry kind="src" path="src/main/resources" excluding="**/*.java"/> <classpathentry kind="output" path="target/classes"/> <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.launching.macosx.MacOSXType/Java SE 8 [1.8.0_121]"/> <classpathentry kind="var" path="M2_REPO/io/netty/netty-all/4.1.30.Final/netty-all-4.1.30.Final.jar" sourcepath="M2_REPO/io/netty/netty-all/4.1.30.Final/netty-all-4.1.30.Final-sources.jar"/> <classpathentry kind="var" path="M2_REPO/javassist/javassist/3.12.1.GA/javassist-3.12.1.GA.jar" sourcepath="M2_REPO/javassist/javassist/3.12.1.GA/javassist-3.12.1.GA-sources.jar"/> </classpath>
Advertisement
Answer
The plugin element should not be inside build->pluginManagement->plugins, but inside build->plugins. Like this
<project> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-shade-plugin</artifactId> <version>3.2.4</version> <executions> <execution> <phase>package</phase> <goals> <goal>shade</goal> </goals> <configuration> <transformers> <transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer"> <mainClass>com.mycompany.app.App</mainClass> </transformer> </transformers> </configuration> </execution> </executions> </plugin> </plugins> </project>