Можно ли использовать Gephi, скомпилированный с IKVM, на веб-сайте?
В настоящее время я пытаюсь загрузить и использовать Gephi Toolkit с веб-сайта.Net 4 C#.
У меня есть версия файла jar инструментария, скомпилированного для виртуальной машины IKVM, которая работает, как и ожидалось, из приложения командной строки, используя следующий код:
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
,
Однако, если я запускаю точно такой же код, с точно такими же, используя операторы и ссылки, самая первая строка загружает ProjectController
экземпляр возвращает ноль.
Я попробовал пару решений
Во-первых, я попытался игнорировать вызов 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) используется в конструкторе, возвращает нуль и затем генерирует исключение.
Во-вторых, отсюда: Lookup в Jython (и Gephi). Я попытался установить%CLASSPATH% в расположение файлов JAR и DLL инструментария.
Есть ли причина, по которой Lookup.getDefault(). Lookup(type) не будет работать в веб-среде? Я не Java-разработчик, поэтому я немного разбираюсь в Java.
Я бы подумал, что можно создать все экземпляры сам, но не смог бы найти способ сделать это.
Я также не могу найти способ понять, почему загрузка ProjectController вернула ноль. Никаких исключений не выдается, и если я не очень тупой, то, похоже, не существует способа увидеть результат попытки загрузки.
Обновление - Ответ
Основываясь на ответе Йеруна Фрайтерса, я решил проблему следующим образом:
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()
мне показалось, что это не сработало, но по предоставленной ссылке я смог найти решение, которое работает во всех случаях.
1 ответ
Это проблема загрузчика классов Java. В приложении командной строки ваш главный исполняемый файл функционирует как загрузчик системного класса и знает, как загружать зависимости сборки, но в веб-процессе нет основного исполняемого файла, поэтому загрузчик системного класса не знает, как загрузить что-либо полезное.
Одним из решений является вызов ikvm.runtime.Startup.addBootClassPathAssemby() для добавления соответствующих сборок в загрузчик загрузочного класса.
Подробнее о проблемах загрузки классов IKVM см. По http://sourceforge.net/apps/mediawiki/ikvm/index.php?title=ClassLoader