gpt4 book ai didi

java - switch 使用未定义的内部类在 tomcat 中导致 NoClassDefFoundError

转载 作者:塔克拉玛干 更新时间:2023-11-03 04:20:11 26 4
gpt4 key购买 nike

我有一个非常简单的枚举

my.package.data.util

public enum Mode
{
SQLEXPORT, PREVIEW, PRINT
}

在另一个类中使用,因为应该使用枚举

my.package.program.ComponentController

switch (_mode) { // line 278, _mode is of type my.package.data.util.Mode
case PREVIEW:
// Do thing for preview
break;
case SQLEXPORT:
// Do thing for SQL
break;
case PRINT:
// Do thing for print
break;
default:
throw new IllegalArgumentException();
}

这两个类在同一个项目中,编译成一个jar文件。

然后一个 Web 项目正在使用这个库(放置在 WEB-INF/lib 文件夹中)。但是,当需要使用这个库,特别是那个开关时,一个 NoClassDefFoundError发生:

NoClassDefFoundError: my/package/program/ComponentController$1

at my.package.program.ComponentController.doCall(ComponentController.java:278)

这是我在几个层面上无法理解的东西:

  1. 为什么 Java 试图加载一个内部类(如 $1 可见)。 ComponentController 中没有内部类,而且从来没有。
  2. 为什么 Java 认为 switch 使用这个内部类作为它的参数
  3. 哪里my.package.data.util.Mode类消失了

这里发生了什么?


原始问题中没有的更多信息

  • ComponentController扩展另一个类,SessionBuilder .这个类也没有内部类

我反编译了 ComponentController使用 javap并试图在生成的字节码中找到有趣的东西。

看来字节码中确实有一个内部类:

public class my.package.program.ComponentController extends my.other.package.SessionBuilder
SourceFile: "ComponentController.java"
InnerClasses:
static #192 of #2; //class my/package/program/ComponentController$1 of class my/package/program/ComponentController

每当 my.package.data.util.Mode 时都会使用此类被引用:

#192 = Class              #486          //  my/package/program/ComponentController$1
#193 = Utf8
#194 = Utf8 InnerClasses
#195 = Utf8 _mode
#196 = Utf8 Lmy/package/data/util/Mode;

而且,当切换实际发生时:

183: getstatic     #102                // Field my/package/program/ComponentController$1.$SwitchMap$my$package$data$util$Mode:[I
186: aload_0
187: getfield #5 // Field _mode:Lmy/package/data/util/Mode;
190: invokevirtual #103 // Method my/package/data/util/Mode.ordinal:()I
193: iaload
194: tableswitch { // 1 to 3
1: 220
2: 335
3: 440
default: 516
}

Rich 链接的问题的进一步调查产生了一些有趣的东西:内置 jar来自库项目的本地 tomcat 安装与用于生成 jar 的不同对于生产服务器:

左: jar 在 WEB-INF/lib通过 eclipse 的本地 tomcat,右:jar由 ANT 构建

JAR Diff

现在看来,当发布到本地 tomcat 时,eclipse 使用的构建过程与 ANT 所做的不同(据我所知,这只是一个简单的 javac 调用)


好吧,现在我刚刚复制了 jar由 ANT 创建到本地 tomcats WEB-INF/lib一切正常。当然,这意味着在库项目每次更改后,我都必须手动复制新的 jar。到我的 tomcat 库。

我在 eclipse 上将此作为错误报告提交,并将报告任何消息。

最佳答案

根据 this问题:

...Sun's Javac 1.6 creates an additional synthetic class each time you use a switch on an Enum.

并根据this怀疑你并不孤单。

关于java - switch 使用未定义的内部类在 tomcat 中导致 NoClassDefFoundError,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28982703/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com