- Java 双重比较
- java - 比较器与 Apache BeanComparator
- Objective-C 完成 block 导致额外的方法调用?
- database - RESTful URI 是否应该公开数据库主键?
首先,这是Java 1.4(项目限制)。我正在尝试创建一个应用程序管理器。它使用自己的自定义类加载器实例加载每个应用程序的主类。之后,它使用反射创建主类的实例。每个应用程序都实现一个公共(public)接口(interface),因此在创建实例后,它会运行应用程序的预定义方法。
但是,我在 CRASH POINT 1 遇到了一些麻烦(见代码)。该类未被识别为其接口(interface)的一种实现。如果我注释这个代码块,我会在崩溃点 2 处得到 ClassCastException。
我想这两个错误都与同一个问题有关(当然)。
谁能帮帮我?代码的相关部分如下(导入已删除)...
非常感谢。
马库斯
//AppManager.java
public class AppManager {
public ThreadGroup threadGroup;
private Class appClass;
private AppInstance appInst;
public AppContextImpl context;
private AppManager(CustomClassLoader cl, String mainClass) throws ClassNotFoundException {
final String className = mainClass;
final CustomClassLoader finalLoader = cl;
appClass = cl.loadClass(mainClass);
// DEBUG CODE:
Class[] k1 = AppInstance.class.getInterfaces();
System.out.println(k1.length + " interfaces for AppInstance.class:");
for (int ii = 0; ii < k1.length; ii++) {
System.out.println(" " + ii + " - " + k1[ii].getName() + " (" + k1[ii].getClassLoader() + ")");
}
Class[] k2 = appClass.getInterfaces();
System.out.println(k2.length + " interfaces for appClass instance:");
for (int ii = 0; ii < k2.length; ii++) {
System.out.println(" " + ii + " - " + k2[ii].getName() + " (" + k2[ii].getClassLoader() + ")");
}
// CRASH POINT 1
if (!(AppInstance.class.isAssignableFrom(appClass))) {
throw new IllegalArgumentException("Attempt to run a non-AppInstance class: " + appClass);
}
context = new AppContextImpl(mainClass, this);
cl.setAppManager(this);
Constructor m;
try {
m = appClass.getConstructor(new Class[0]);
// CRASH POINT 2
appInst = (AppInstance) m.newInstance(new Object[0]);
appInst.init(context);
} catch (Exception e) {
System.out.println("Got ClassCastException here!\n");
e.printStackTrace();
}
}
public static void main(String[] args) {
App app1;
String path1 = "/home/user/workspace/MultiTaskTest/bin/";
String app1Name = "App1";
Vector v1 = new Vector();
try {
v1.add(new URL(path1));
} catch (MalformedURLException e1) {
final File file1 = new File(path1);
try {
URL path1aux = (URL) AccessController.doPrivileged(
new PrivilegedExceptionAction() {
public Object run() throws IOException {
if (!file1.exists()) {
System.out.println("Warning: \"" + file1.getPath() + "\" not found");
return null;
}
return file1.toURI().toURL();
}
});
if (path1aux != null) {
v1.add(path1aux);
}
} catch (PrivilegedActionException e) {
e.getException().printStackTrace();
}
}
final URL[] array1 = (URL[]) v1.toArray(new URL[v1.size()]);
CustomClassLoader cl1 = (CustomClassLoader) AccessController.doPrivileged(
new PrivilegedAction() { public Object run() {
return new CustomClassLoader(array1);
}});
System.out.println("ClassLoader 1 created: " + cl1);
try {
app1 = new App(cl1, app1Name);
} catch (ClassNotFoundException e) {
e.printStackTrace();
System.out.println("Cannot find class App1.");
}
}
}
//应用实例.java
public interface AppInstance {
public void init(ContextImpl context);
}
//App1.java
public class App1 implements AppInstance {
private AppContextImpl contextObj;
public void init(AppContextImpl context) {
this.contextObj = context;
System.out.println("Running App1...");
}
}
//AppContextImpl.java
public class AppContextImpl {
public String mainClass;
public AppManager app;
public AppContextImpl(String mainClass, AppManager app) {
this.mainClass = mainClass;
this.app = app;
}
}
//自定义类加载器.java
public class CustomClassLoader extends URLClassLoader {
AppManager appInst;
public CustomClassLoader(URL[] paths) { super(paths, null); }
public void setAppManager(AppManager app) { this.appInst = app; }
}
AppManager.java 文件中调试代码的输出是:
0 interfaces for AppInstance.class:
1 interfaces for appClass instance:
0 - AppInstance (CustomClassLoader@480457)
最佳答案
您的 AppInstance 类可能由每个自定义类加载器单独加载。由于类对象依赖于实际的类和类加载器,它们实际上是不同的类。所以来自类加载器 1 的 AppInstance 与来自类加载器 2 的 AppInstance 不同。
您需要做的是使用标准的类加载器层次结构:为您的应用程序使用根类加载器,并确保 AppInstance 可由类加载器加载。然后让你的自定义类加载器从根开始。每当他们需要访问 AppInstance 类时,他们将使用从根加载的内容。
所以,而不是这个:
public CustomClassLoader(URL[] paths) { super(paths, null); }
您需要为您的 CustomClassLoader 提供父级
关于java - 使用反射和 ClassLoaders 创建类的实例时出现 ClassCastException,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2999824/
我只是想知道如果我知道类加载器,我是否可以在 JVM 运行时获取类的实例(对对象的引用)。请引用下面的代码来理解我的问题。 A类: package local.run; public class A
我们正在尝试调试 WebStart 的一个不可重现的问题,即访问 Jars 内的资源将“随机”失败。也许每 1000 个应用程序运行中就有一个会出现此错误,这种错误可能发生在从 jar 读取资源的任何
在从属实例(AIX 5.3 上的主服务器;Windows 2008(R2) 上的从属服务器)上运行 Maven2 作业时,我收到以下消息(下面粘贴了完整的堆栈跟踪):“java.lang.ClassN
我正在编写一个游戏引擎,我需要在其中分析程序中提到的每个类。由于这是一个游戏引擎,因此它将作为 JAR 文件附加到客户的项目中。从该 JAR 文件中,我需要能够扫描客户端正在使用的每个类。 所以我想我
Java安全之BCEL ClassLoader 写在前面 BCEL平常在测试反序列化的时候也经常会用到,比如延时测Gadget以及在某些场景下执行命令不是那么顺手的情况下选择BCEL去打内存马,就像F
比如说,我有一个 A 类,由 ClassLoader CL1 加载。 我有另一个 B 类,由 ClassLoader CL2 加载。 假设这两个类现在都由各自的类加载器加载。 如果我从 A 执行以下语
在 org.dozer.BeanFactory.createBean(Object, Class, String) 的实现中我尝试将对象转换为它的类型。如果我部署所有 bundle ,即关闭并启动所有
它过去曾经可以工作,但是我中间没有发生什么,现在它总是返回null。 要读取的文件在项目root diretory中,该项目与Paths.get(".")的输出相对应。 注意:功能是顶级的 我正在读取
在 org.dozer.BeanFactory.createBean(Object, Class, String) 的实现中我尝试将对象转换为它的类型。如果我部署我所有的包,即关闭并启动所有包,我得到
我必须使用第 3 方平台,但该平台具有无法替换的较旧版本的 jar libjar-1.0.0.jar。该平台允许我在其上运行我自己的(平面文件)包。我将新版本的 libjar-2.0.0.jar 放在
我正在尝试使用下面的类加载器在我的 Maven 插件中加载特定的类: public ClassLoader getClassLoader(MavenProject project) { tr
以下场景: CustomClassLoaderA 加载 ClassA CustomClassLoaderB 加载 ClassB 到目前为止一切顺利,但是: CustomClassLoaderA 应该能
我试图强制使用我的自定义类加载器加载某些类,问题是在加载调用类之后仍然不知道类定义并尝试再次加载它,当然之后我们对该类有两种不同的定义,并将一种定义分配给另一种会导致类转换异常。有什么建议或想法可以解
我在尝试指示 Java 类加载器在部署后从 test/resources 目录中检索 JSON 文件时遇到了问题。 public class TestFileUtil { private st
我似乎在为我正在开发的应用程序的模块加载器中加载类时遇到问题。基本上,我将用它加载的所有类都扩展了另一个类,该类位于实际应用程序的包中。出于我们的目的,我们将其称为模块。模块位于实际应用程序之外的单独
关闭。这个问题需要details or clarity .它目前不接受答案。 想改进这个问题吗? 通过 editing this post 添加细节并澄清问题. 关闭 8 年前。 Improve t
我正在使用 URLClassLoader 创建一个新的类加载器,并尝试将其设置为当前线程的类加载器。但它对我来说不能正常工作。按照我的理解,如果我给当前线程设置一个classLoader,那么当前线程
昨天我想到了一个问题,下面是细节: 我有 3 个 JAR 文件,a.jar、b.jar、c.jar。这两个 jars 文件都有一个名为 com.test.Test 的类,并且 sayHello() 是
我想创建一个新的 ClassLoader 实例,它在开始时绝对不包含任何类。它不应该有一个可用的类。甚至没有 java.lang 类。我希望能够为我自己的位置手动加载每个类。 (使用覆盖的 defin
我正在开发一个个人用药时间提醒应用程序。除了在通知几次用药时间后停止之外,它几乎可以正常工作。在监视应用程序的日志猫时,我发现它在收到以下警告后正在停止警报接收器。 W/System: ClassLo
我是一名优秀的程序员,十分优秀!