当前位置: 首页 > 知识库问答 >
问题:

模拟具有静态枚举类的类时出现“无法转换具有名称的类”错误

林德惠
2023-03-14
java.lang.IllegalStateException: Failed to transform class with name com.XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX$ReadSets. Reason: null
    at org.powermock.core.classloader.MockClassLoader.loadMockClass(MockClassLoader.java:219)
    at org.powermock.core.classloader.MockClassLoader.loadModifiedClass(MockClassLoader.java:147)
    at org.powermock.core.classloader.DeferSupportingClassLoader.loadClass(DeferSupportingClassLoader.java:67)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:356)
    at java.lang.Class.forName0(Native Method)
    at java.lang.Class.forName(Class.java:264)
    at sun.reflect.generics.factory.CoreReflectionFactory.makeNamedType(CoreReflectionFactory.java:114)
    at sun.reflect.generics.visitor.Reifier.visitClassTypeSignature(Reifier.java:125)
    at sun.reflect.generics.tree.ClassTypeSignature.accept(ClassTypeSignature.java:49)
    at sun.reflect.annotation.AnnotationParser.parseSig(AnnotationParser.java:390)
    at sun.reflect.annotation.AnnotationParser.parseClassValue(AnnotationParser.java:371)
    at sun.reflect.annotation.AnnotationParser.parseClassArray(AnnotationParser.java:673)
    at sun.reflect.annotation.AnnotationParser.parseArray(AnnotationParser.java:480)
    at sun.reflect.annotation.AnnotationParser.parseMemberValue(AnnotationParser.java:306)
    at sun.reflect.annotation.AnnotationParser.parseAnnotation(AnnotationParser.java:241)
    at sun.reflect.annotation.AnnotationParser.parseAnnotations2(AnnotationParser.java:88)
    at sun.reflect.annotation.AnnotationParser.parseAnnotations(AnnotationParser.java:70)
    at java.lang.Class.initAnnotationsIfNecessary(Class.java:3089)
    at java.lang.Class.getAnnotations(Class.java:3069)
    at org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl.classAnnotations(PowerMockJUnit44RunnerDelegateImpl.java:163)
    at org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl.getDescription(PowerMockJUnit44RunnerDelegateImpl.java:155)
    at org.powermock.modules.junit4.common.internal.impl.JUnit4TestSuiteChunkerImpl.getDescription(JUnit4TestSuiteChunkerImpl.java:171)
    at org.powermock.modules.junit4.common.internal.impl.AbstractCommonPowerMockRunner.getDescription(AbstractCommonPowerMockRunner.java:47)
    at org.eclipse.jdt.internal.junit4.runner.JUnit4TestClassReference.sendTree(JUnit4TestClassReference.java:38)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.sendTrees(RemoteTestRunner.java:476)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:464)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)
Caused by: java.lang.NullPointerException
    at javassist.compiler.MemberResolver.lookupMethod(MemberResolver.java:110)
    at javassist.compiler.MemberResolver.lookupMethod(MemberResolver.java:96)
    at javassist.compiler.TypeChecker.atMethodCallCore(TypeChecker.java:704)
    at javassist.compiler.TypeChecker.atCallExpr(TypeChecker.java:681)
    at javassist.compiler.JvstTypeChecker.atCallExpr(JvstTypeChecker.java:156)
    at javassist.compiler.ast.CallExpr.accept(CallExpr.java:45)
    at javassist.compiler.Javac$1.setReturnType(Javac.java:449)
    at javassist.compiler.JvstTypeChecker.atCallExpr(JvstTypeChecker.java:146)
    at javassist.compiler.ast.CallExpr.accept(CallExpr.java:45)
    at javassist.compiler.TypeChecker.atVariableAssign(TypeChecker.java:248)
    at javassist.compiler.TypeChecker.atAssignExpr(TypeChecker.java:217)
    at javassist.compiler.ast.AssignExpr.accept(AssignExpr.java:38)
    at javassist.compiler.CodeGen.doTypeCheck(CodeGen.java:235)
    at javassist.compiler.CodeGen.atStmnt(CodeGen.java:323)
    at javassist.compiler.ast.Stmnt.accept(Stmnt.java:49)
    at javassist.compiler.CodeGen.atStmnt(CodeGen.java:344)
    at javassist.compiler.ast.Stmnt.accept(Stmnt.java:49)
    at javassist.compiler.CodeGen.atIfStmnt(CodeGen.java:384)
    at javassist.compiler.CodeGen.atStmnt(CodeGen.java:348)
    at javassist.compiler.ast.Stmnt.accept(Stmnt.java:49)
    at javassist.compiler.CodeGen.atStmnt(CodeGen.java:344)
    at javassist.compiler.ast.Stmnt.accept(Stmnt.java:49)
    at javassist.compiler.Javac.compileStmnt(Javac.java:558)
    at javassist.expr.MethodCall.replace(MethodCall.java:233)
    at org.powermock.core.transformers.impl.MainMockTransformer$PowerMockExpressionEditor.edit(MainMockTransformer.java:299)
    at javassist.expr.ExprEditor.loopBody(ExprEditor.java:178)
    at javassist.expr.ExprEditor.doit(ExprEditor.java:90)
    at javassist.CtClassType.instrument(CtClassType.java:1224)
    at org.powermock.core.transformers.impl.MainMockTransformer.transform(MainMockTransformer.java:75)
    at org.powermock.core.classloader.MockClassLoader.loadMockClass(MockClassLoader.java:215)
    ... 28 more

这个类包含一个静态方法getInstance(我想模拟它),以提供一个singleton对象和几个声明为公共静态的枚举类(在异常中可以看到其中一个名为ReadSets的类)。下面是这个类的样子。

有没有关于如何修复的线索?

public class XXX extends YYY {

    private volatile static XXX s_instance;

    public static XXX getInstance() {
        if (s_instance == null)
            synchronized (XXX.class) {
                if (s_instance == null)
                    s_instance = new XXX();
            }
        return s_instance;
    }

    public static enum ReadSets {
        ANY(1), ALL(2);
        int val;

        public int getVal() {
            return val;
        }

        private ReadSets(int v) {
            val = v;
        }
    }

    public static enum UpdateSets {
        ANY(1), ALL(2);
        int val;

        private UpdateSets(int v) {
            val = v;
        }
    }

    // [...]

}

共有1个答案

祁景山
2023-03-14

我在一次测试中遇到了同样的问题,对我来说,这是由冲突的Javassist版本引起的。一些依赖项使用javassist.javassist-3.4.ga,而PowerMock使用org.javassist.javassist-3.18.1-ga(org.是主要区别)。似乎是eclipse先将前一个放入类路径中,因此使用了较旧的版本。

我使用maven,因此我可以通过在拉动javassist.javassist的依赖项中创建一个排除规则来解决冲突,并直接依赖于较新的jassist版本。这不是最好的解决方法,但我不知道在Maven中处理这些人工操作的更好方法。

<dependency>
  <groupId>some</groupId>
  <artifactId>dependency</artifactId>
  <version>1.0</version>
  <exclusions>
    <exclusion>
      <groupId>javassist</groupId>
      <artifactId>javassist</artifactId>
    </exclusion>
  </exclusions>
</dependency>
<dependency>
  <groupId>org.javassist</groupId>
  <artifactId>javassist</artifactId>
  <version>3.18.2-GA</version>
</dependency>

当然,您必须检查依赖关系是否仍然适用于该版本。

 类似资料:
  • 枚举类(“新的枚举”/“强类型的枚举”)主要用来解决传统的C++枚举的三个问题: 传统C++枚举会被隐式转换为int,这在那些不应被转换为int的情况下可能导致错误 传统C++枚举的每一枚举值在其作用域范围内都是可见的,容易导致名称冲突(同名冲突) 不可以指定枚举的底层数据类型,这可能会导致代码不容易理解、兼容性问题以及不可以进行前向声明 枚举类(enum)(“强类型枚举”)是强类型的,并且具有类

  • 问题内容: 假设我有一个像这样的课程: 如何使用简单的模拟方法模拟静态方法调用?。 我正在使用简单的模拟3.0 问题答案: 不知道如何使用纯EasyMock,但可以考虑使用EasyMock 的PowerMock扩展。 它具有很多很酷的功能,可以满足您的需要 -https://github.com/jayway/powermock/wiki/MockStatic

  • 问题内容: 想知道是否有人在使用新功能通过PHP 5.3对类进行命名空间时是否遇到了此问题。 我正在使用单独的类来生成动态类调用,以在应用程序中定义用户类型。基本上,类定义器采用类型的整数表示形式并解释它们,返回一个包含要用作该用户模型的类名的字符串。 我在全局范围内定义了具有该名称的用户类型的对象模型,但是在Editor名称空间中,该用户的编辑器具有另一个名称相同的对象。由于某些原因,PHP不允

  • 我遇到了以下javac编译失败,javac无法识别具有公共枚举的静态嵌套类上的注释。一旦我将枚举移出静态嵌套类,编译错误就得到了解决。有人知道javac失败的原因吗?这是java编译器错误吗?还是有我不知道的java细微差别? 下面是一个独立的测试用例。 未能编译: 编译输出: 编译: 无错误编译: 需要指出的事情: 1)注意编译失败的行号解析NestedClassNoEnum的注释没有问题。 2

  • 问题内容: 基本上,我所做的是为州写一个枚举,我不仅希望能够像州一样访问它们,而且还希望访问它们的缩写以及它们是否是原始殖民地。 这似乎按我预期的那样工作。我可以 对于涉及枚举的特定情况,这是执行此操作的最佳方法,还是设置和格式化此枚举的更好方法?预先感谢所有人! 问题答案: 首先,枚举方法不应大写。它们是与其他方法一样的方法,具有相同的命名约定。 其次,您所做的并不是建立枚举的最佳方法。不要为每