java - 为什么我的maven构建在执行时找不到Netty的EventLoopGroup类?

标签 java maven netty

我按照 Netty 的文档编写了代码,然后执行:

mvn package

构建成功。然后我运行:

java -jar target/netty-listener-0.0.1-SNAPSHOT.jar

它提示我这个错误:

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

据我了解,JRE 在执行时没有找到 Netty 的 EventLoopGroup 类。在 Eclipse 中,我看到 Maven 的依赖项选项卡上的 netty-all 依赖项和 EventLoopGroup 都在那里。我多次尝试更改 Netty 的版本但不起作用。

这是我的主要代码:

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();
    }
    
}

它几乎与 Netty 文档中的代码完全相同,但它在管道的开头添加了一个解码器。

这是我的 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> 

我该如何解决这个问题?

EDIT1:将 maven-shade-plugin 添加到 pom.xml 但(相同)问题仍然存在。

添加到 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>

编辑2:将artifactSet添加到pom.xml,但它不起作用

<artifactSet>
    <includes>
            <include>io.netty:*</include>
    </includes>
</artifactSet>

我也尝试了 * : *,正如 Yuri G. 所建议的。

EDIT3: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

看起来 netty 没有被复制到 jar 文件中。但我还是不知道如何解决。我将在此处链接生成的 .classpath(我猜 Eclipse 生成了它):

<?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>

最佳答案

plugin 元素不应位于 build->pluginManagement->plugins 内,而应位于 build->plugins 内。像这样

<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>

关于java - 为什么我的maven构建在执行时找不到Netty的EventLoopGroup类?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64542206/

相关文章:

java - 如何在到达指定位置后旋转矩形?

java - 如何在Java中获取HTTP错误400的响应json

java - 在 Spring MVC 中实现 XSLT View

java - 如何使用maven制作可执行jar?

java - 在 pom.xml 中包含 proguard 配置文件

java-8 - Java 检查平台是否支持 sctp,否则使用 tcp

java - 为什么 H2 数据库仅在某些测试中告诉我我的表不存在

java - 在 Netty 4.0 中创建一个 ByteBuf

java - 如何在各种消息事件之间传递参数

java - 通过 Cygwin 部署 java