我目前正在尝试从 .Net 4 C# 网站中加载和使用Gephi 工具包。
我有一个针对 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 然后引发异常。
其次,从这里开始:在 Jython(和 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()
似乎对我不起作用,但从提供的链接中,我能够找到似乎在所有情况下都有效的解决方案。