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

huangapple go评论123阅读模式
英文:

Why is my maven build not finding Netty's EventLoopGroup class when executing?

问题

我根据你提供的内容为你翻译如下:

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

mvn package

它成功构建了。然后我运行了:

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

但是它给我返回了这个错误:

> 异常线程 "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:

<!-- 在这里是你的pom.xml内容 -->

我应该如何解决这个问题?

编辑1:向pom.xml添加了maven-shade-plugin,但(相同的)问题仍然存在。

添加到pom的行:

<!-- 在这里是你向pom.xml添加的内容 -->

编辑2:向pom.xml添加了artifactSet,但没有起作用。

<!-- 在这里是你向pom.xml添加的内容 -->

我还尝试了 * : *,就像Yuri G.建议的一样。

编辑3:unzip -l的内容:

<!-- 在这里是unzip -l的内容 -->

看起来netty没有被复制到jar文件中。但我仍然不知道如何解决它。我会在这里链接生成的.classpath文件(我猜是Eclipse生成的):

<!-- 在这里是.classpath的内容 -->

这些是我翻译好的部分,关于具体的问题和解决方案,请查阅原文。

英文:

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&lt;SocketChannel&gt;() {
@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 &gt; 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:

&lt;project xmlns=&quot;http://maven.apache.org/POM/4.0.0&quot; xmlns:xsi=&quot;http://www.w3.org/2001/XMLSchema-instance&quot; xsi:schemaLocation=&quot;http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd&quot;&gt;
&lt;modelVersion&gt;4.0.0&lt;/modelVersion&gt;
&lt;groupId&gt;neurony.listener&lt;/groupId&gt;
&lt;artifactId&gt;netty-listener&lt;/artifactId&gt;
&lt;version&gt;0.0.1-SNAPSHOT&lt;/version&gt;
&lt;packaging&gt;jar&lt;/packaging&gt;
&lt;dependencies&gt;
&lt;dependency&gt;
&lt;groupId&gt;io.netty&lt;/groupId&gt;
&lt;artifactId&gt;netty-all&lt;/artifactId&gt;
&lt;version&gt;4.1.53.Final&lt;/version&gt;
&lt;scope&gt;compile&lt;/scope&gt;
&lt;/dependency&gt;
&lt;dependency&gt;
&lt;groupId&gt;javassist&lt;/groupId&gt;
&lt;artifactId&gt;javassist&lt;/artifactId&gt;
&lt;version&gt;3.12.1.GA&lt;/version&gt;
&lt;/dependency&gt;
&lt;/dependencies&gt;
&lt;build&gt;
&lt;pluginManagement&gt;
&lt;plugins&gt;
&lt;plugin&gt;
&lt;groupId&gt;org.apache.maven.plugins&lt;/groupId&gt;
&lt;artifactId&gt;maven-compiler-plugin&lt;/artifactId&gt;
&lt;version&gt;3.1&lt;/version&gt;
&lt;configuration&gt;
&lt;source&gt;1.8&lt;/source&gt;
&lt;target&gt;1.8&lt;/target&gt;
&lt;/configuration&gt;
&lt;/plugin&gt;
&lt;plugin&gt;
&lt;groupId&gt;org.apache.maven.plugins&lt;/groupId&gt;
&lt;artifactId&gt;maven-jar-plugin&lt;/artifactId&gt;
&lt;version&gt;2.4&lt;/version&gt;
&lt;configuration&gt;
&lt;archive&gt;
&lt;manifest&gt;
&lt;mainClass&gt;paplistener.PAPServer&lt;/mainClass&gt;
&lt;/manifest&gt;
&lt;/archive&gt;
&lt;/configuration&gt;
&lt;/plugin&gt;
&lt;plugin&gt;
&lt;groupId&gt;org.apache.maven.plugins&lt;/groupId&gt;
&lt;artifactId&gt;maven-dependency-plugin&lt;/artifactId&gt;
&lt;version&gt;2.5.1&lt;/version&gt;
&lt;executions&gt;
&lt;execution&gt;
&lt;id&gt;copy-dependencies&lt;/id&gt;
&lt;phase&gt;package&lt;/phase&gt;
&lt;goals&gt;
&lt;goal&gt;copy-dependencies&lt;/goal&gt;
&lt;/goals&gt;
&lt;configuration&gt;
&lt;outputDirectory&gt;
${project.build.directory}/dependency-jars/
&lt;/outputDirectory&gt;
&lt;/configuration&gt;
&lt;/execution&gt;
&lt;/executions&gt;
&lt;/plugin&gt;
&lt;/plugins&gt;
&lt;/pluginManagement&gt;
&lt;/build&gt;
&lt;/project&gt; 

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:

        &lt;plugin&gt;
&lt;groupId&gt;org.apache.maven.plugins&lt;/groupId&gt;
&lt;artifactId&gt;maven-shade-plugin&lt;/artifactId&gt;
&lt;version&gt;3.2.4&lt;/version&gt;
&lt;executions&gt;
&lt;execution&gt;
&lt;phase&gt;package&lt;/phase&gt;
&lt;goals&gt;
&lt;goal&gt;shade&lt;/goal&gt;
&lt;/goals&gt;
&lt;configuration&gt;
&lt;transformers&gt;
&lt;transformer implementation=&quot;org.apache.maven.plugins.shade.resource.ManifestResourceTransformer&quot;&gt;
&lt;manifestEntries&gt;
&lt;Main-Class&gt;paplistener.PAPServer&lt;/Main-Class&gt;
&lt;Build-Number&gt;1&lt;/Build-Number&gt;
&lt;/manifestEntries&gt;
&lt;/transformer&gt;
&lt;/transformers&gt;
&lt;/configuration&gt;
&lt;/execution&gt;
&lt;/executions&gt;
&lt;/plugin&gt;

EDIT2: added artifactSet to pom.xml but it didn't work

&lt;artifactSet&gt;
&lt;includes&gt;
&lt;include&gt;io.netty:*&lt;/include&gt;
&lt;/includes&gt;
&lt;/artifactSet&gt;

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

&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;
&lt;classpath&gt;
&lt;classpathentry kind=&quot;src&quot; path=&quot;src/test/java&quot; output=&quot;target/test-classes&quot; including=&quot;**/*.java&quot;/&gt;
&lt;classpathentry kind=&quot;src&quot; path=&quot;src/test/resources&quot; output=&quot;target/test-classes&quot; excluding=&quot;**/*.java&quot;/&gt;
&lt;classpathentry kind=&quot;src&quot; path=&quot;src/main/java&quot; including=&quot;**/*.java&quot;/&gt;
&lt;classpathentry kind=&quot;src&quot; path=&quot;src/main/resources&quot; excluding=&quot;**/*.java&quot;/&gt;
&lt;classpathentry kind=&quot;output&quot; path=&quot;target/classes&quot;/&gt;
&lt;classpathentry kind=&quot;con&quot; path=&quot;org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.launching.macosx.MacOSXType/Java SE 8 [1.8.0_121]&quot;/&gt;
&lt;classpathentry kind=&quot;var&quot; path=&quot;M2_REPO/io/netty/netty-all/4.1.30.Final/netty-all-4.1.30.Final.jar&quot; sourcepath=&quot;M2_REPO/io/netty/netty-all/4.1.30.Final/netty-all-4.1.30.Final-sources.jar&quot;/&gt;
&lt;classpathentry kind=&quot;var&quot; path=&quot;M2_REPO/javassist/javassist/3.12.1.GA/javassist-3.12.1.GA.jar&quot; sourcepath=&quot;M2_REPO/javassist/javassist/3.12.1.GA/javassist-3.12.1.GA-sources.jar&quot;/&gt;
&lt;/classpath&gt;

答案1

得分: 1

你缺少了classpath。Eclipse 管理它自己的classpath,这就是为什么在Eclipse中可以工作。

创建一个可以通过 java -jar 直接执行的 jar 文件的最简单方法是使用 maven-shade-plugin。你可以查看文档,了解如何使用 maven-shade-plugin 创建可执行的jar文件。

更新
你需要配置要包含在shaded jar中的构件,可以参考这里的描述。例如,如果你想要包括所有依赖项,包括传递依赖,可以按照以下方式进行配置:

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-shade-plugin</artifactId>
    <version>3.2.4</version>
    <configuration>
        <artifactSet>
            <includes>
                <include>*:*</include>
            </includes>
        </artifactSet>
        <shadedArtifactAttached>false</shadedArtifactAttached>
    </configuration>
    <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>

你可以在文档页面 https://maven.apache.org/plugins/maven-shade-plugin/shade-mojo.html 找到所有可用的配置项。

英文:

You're missing the classpath. Eclipse manages its own classpath, that's why it works in Eclipse.

The easiest way to create a jar file that can be executed simply by java -jar is to use a maven-shade-plugin. You can check the documentation for how to create an executable jar with maven-shade-plugin.

Update:
You need to configure which artifacts to include in the shaded jar as described here. For example if you want include all dependencies including transitive, you can do as following:

&lt;plugin&gt;
&lt;groupId&gt;org.apache.maven.plugins&lt;/groupId&gt;
&lt;artifactId&gt;maven-shade-plugin&lt;/artifactId&gt;
&lt;version&gt;3.2.4&lt;/version&gt;
&lt;configuration&gt;
&lt;artifactSet&gt;
&lt;includes&gt;
&lt;include&gt;*:*&lt;/include&gt;
&lt;/includes&gt;
&lt;/artifactSet&gt;
&lt;shadedArtifactAttached&gt;false&lt;/shadedArtifactAttached&gt;
&lt;/configuration&gt;
&lt;executions&gt;
&lt;execution&gt;
&lt;phase&gt;package&lt;/phase&gt;
&lt;goals&gt;
&lt;goal&gt;shade&lt;/goal&gt;
&lt;/goals&gt;
&lt;configuration&gt;
&lt;transformers&gt;
&lt;transformer implementation=&quot;org.apache.maven.plugins.shade.resource.ManifestResourceTransformer&quot;&gt;
&lt;manifestEntries&gt;
&lt;Main-Class&gt;paplistener.PAPServer&lt;/Main-Class&gt;
&lt;Build-Number&gt;1&lt;/Build-Number&gt;
&lt;/manifestEntries&gt;
&lt;/transformer&gt;
&lt;/transformers&gt;
&lt;/configuration&gt;
&lt;/execution&gt;
&lt;/executions&gt;
&lt;/plugin&gt;

You can see all available configuration in the doc's page https://maven.apache.org/plugins/maven-shade-plugin/shade-mojo.html

答案2

得分: 1

<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>
英文:

The plugin element should not be inside build->pluginManagement->plugins, but inside build->plugins. Like this

&lt;project&gt;
&lt;plugins&gt;
&lt;plugin&gt;
&lt;groupId&gt;org.apache.maven.plugins&lt;/groupId&gt;
&lt;artifactId&gt;maven-shade-plugin&lt;/artifactId&gt;
&lt;version&gt;3.2.4&lt;/version&gt;
&lt;executions&gt;
&lt;execution&gt;
&lt;phase&gt;package&lt;/phase&gt;
&lt;goals&gt;
&lt;goal&gt;shade&lt;/goal&gt;
&lt;/goals&gt;
&lt;configuration&gt;
&lt;transformers&gt;
&lt;transformer implementation=&quot;org.apache.maven.plugins.shade.resource.ManifestResourceTransformer&quot;&gt;
&lt;mainClass&gt;com.mycompany.app.App&lt;/mainClass&gt;
&lt;/transformer&gt;
&lt;/transformers&gt;
&lt;/configuration&gt;
&lt;/execution&gt;
&lt;/executions&gt;
&lt;/plugin&gt;
&lt;/plugins&gt;
&lt;/project&gt;

huangapple
  • 本文由 发表于 2020年10月27日 01:37:18
  • 转载请务必保留本文链接:https://go.coder-hub.com/64542206.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定