我目前正在尝试从.Net 4 C#网站加载和使用Gephi Toolkit。
我有一个针对IKVM虚拟机编译的工具包jar文件的版本,它使用以下代码从命令行应用程序按预期工作:
var controller = (ProjectController)Lookup.getDefault().lookup(typeof(ProjectController));
controller.closeCurrentProject();
controller.newProject();
var project = controller.getCurrentProject();
var workspace = controller.getCurrentWorkspace();
三个实例以类似于org.gephi.project.impl.ProjectControllerImpl@8ddb93
的形式正确实例化。
但是,如果我运行完全相同的代码,使用完全相同的using语句&引用,加载ProjectController
实例的第一行返回null。
我尝试了几种解决方案
首先,我尝试忽略Lookup.getDefault()。lookup(type)调用,而不是尝试创建自己的实例:
var controller = new ProjectControllerImpl();
controller.closeCurrentProject();
controller.newProject();
var project = controller.getCurrentProject();
var workspace = controller.getCurrentWorkspace();
这在行controller.newProject();失败了,我认为因为内部(使用反射器)相同的Lookup.getDefault()。在构造函数中使用了lookup(type),返回null然后抛出异常。 / p>
其次,从这里开始:Lookup in Jython (and Gephi)我试图将%CLASSPATH%设置为工具箱JAR和DLL文件的位置。
有没有理由说Lookup.getDefault()。lookup(type)在Web环境中不起作用?我不是Java开发人员,因此我对Java方面有点不了解。
我原本以为可以自己创建所有实例,但是无法找到方法。
我也找不到一种方法来查看为什么ProjectController加载返回null。没有异常被抛出,除非我非常愚蠢,否则似乎没有一种方法可以看到尝试加载的结果。
更新 - 回答
根据Jeroen Frijters的回答,我解决了这个问题:
public class Global : System.Web.HttpApplication
{
public Global()
{
var assembly = Assembly.LoadFrom(Path.Combine(root, "gephi-toolkit.dll"));
var acl = new AssemblyClassLoader(assembly);
java.lang.Thread.currentThread().setContextClassLoader(new MySystemClassLoader(acl));
}
}
internal class MySystemClassLoader : ClassLoader
{
public MySystemClassLoader(ClassLoader parent)
: base(new AppDomainAssemblyClassLoader(typeof(MySystemClassLoader).Assembly))
{ }
}
代码ikvm.runtime.Startup.addBootClassPathAssemby()
似乎对我不起作用,但是从提供的链接中,我能够找到似乎适用于所有实例的解决方案。
答案 0 :(得分:0)
这是一个Java类加载器问题。在命令行应用程序中,您的主可执行文件充当系统类加载器并知道如何加载程序集依赖项,但在Web进程中没有主可执行文件,因此系统类加载器不知道如何加载任何有用的东西。
其中一个解决方案是调用ikvm.runtime.Startup.addBootClassPathAssemby()将相关程序集添加到引导类加载器。
有关IKVM类加载问题的更多信息,请参阅http://sourceforge.net/apps/mediawiki/ikvm/index.php?title=ClassLoader