2

对于一些特殊的用例,我有一个小实用程序可以使用动态类加载器从 jar 中加载 Java 类DynamicClassLoader。这适用于 jar 中包含的 Java 类。从 jar 加载 Scala 类也没有问题。但是,实例化加载的 Scala 类会导致以下异常。看起来 Scala 类有私有默认构造函数?注意编译后的 Scala 类名以$

java.lang.IllegalAccessException: Class XXX can not access a member of class ScalaClassYYY$ with modifiers "private"

下面的代码片段说明了我想要实现的目标,并提供了更多背景信息。异常发生在注释行:

// deploy and register the new code
byte[] jarBytes = (byte[]) ((Object) message.getAttachment("jar"));
String registerClassName = message.getAttachment("register");
logger.debug("the register is '" + registerClassName + "'");

DynamicClassLoader loader = new DynamicClassLoader(jarBytes);
Class<?> registerClass = loader.lookUp(registerClassName);
// ===> this is where the java.lang.IllegalAccessException happens 
IRegisterExecutor registerExecutor = (IRegisterExecutor) registerClass.newInstance();
registerExecutor.register();

任何想法如何解决?

4

1 回答 1

5

显然,您需要公开默认构造函数(它也不适用于没有公共默认构造函数的 Java 类)。例如

class ScalaClassYYY() {
  ...
}

或者如果你想让主构造函数接受一些参数,

class ScalaClassYYY(arg1: Int) {
  def this() = this(0)
}

但从

注意编译后的 Scala 类名以$

似乎您实际上是在尝试实例化 Scala object

object ScalaClassYYY { ... }

在这种情况下,您不应创建新实例,而应使用现有实例:

(IRegisterExecutor) registerClass.getField("MODULE$").get(null);

编辑:

我在您的回答中看不到如何将默认公共构造函数添加到不需要任何参数的 Scala 类中。

不需要任何参数的class不是)已经有一个默认的公共构造函数(我的第一个例子)。object

实际上,在 Java 中,所有类都默认提供一个公共的默认构造函数

不,只有那些没有带参数的构造函数的类。

删除“(它也不适用于没有公共默认构造函数的 Java 类)”,因为它是错误的

文档Class.newInstance()说_

IllegalAccessException- 如果类或其 nullary 构造函数不可访问。

所以我很确定这是对的。如果它确实适用于没有公共默认构造函数的 Java 类,那么这似乎是您使用的类加载器中的一个主要错误。您可以使用如下所示的 Java 类对其进行测试:

public class TestClass implements IRegisterExecutor {
    public TestClass(int dummy) {}

    // some implementation for IRegisterExecutor methods to get it to compile
}
于 2013-07-01T10:54:57.300 回答