2013-12-18 2 views
1

Я пытаюсь создать настольное приложение с помощью E4 с его окружением OSGi (Equinox). Для моей безопасности пользователей я использую Сиро. Но я могу загрузить класс из моего OSGi, но не могу!Как загрузить класс в среде OSGI E4 при использовании Shiro?

В моей Bundle я попробовать это:

InitActivator.java:

public class InitActivator implements BundleActivator { 
private static BundleContext context; 

static BundleContext getContext() { 
    return context; 
} 

@Override 
public void start(BundleContext context) throws Exception { 

    //1. OSGi loadClass function 
    System.err.println(context.getBundle().loadClass("com.firm.demo.MyCustomClass") 
        .getName()); 
    //2. Using Apache Shiro ClassUtils 
    System.err.println("Shiro : " + ClassUtils.forName("com.firm.demo.MyCustomClass")); 

    } 

} 

1. System.err вернуть правильный класс с его составным именем. 2. System.err возвращают org.apache.shiro.util.UnknownClassException: Не удается загрузить класс с именем

Как я могу использовать Shiro в OSGi, чтобы найти класс с именем?

ответ

2

Если посмотреть на источник ClassUtils, вы увидите, как он пытается загрузить классы: http://grepcode.com/file/repo1.maven.org/maven2/org.apache.shiro/shiro-core/1.0.0-incubating/org/apache/shiro/util/ClassUtils.java#ClassUtils.forName%28java.lang.String%29

первое, что он пытается это загрузить класс с помощью ClassLoader, прикрепленного к нити. Если он не работает, он пытается загрузить с помощью ClassLoader, который загружает ClassUtils. Если это не удается, он пытается загрузить класс с помощью системы ClassLoader.

Вы можете обмануть первый из них - загрузчик классов контекста потока. Я должен упомянуть, что это всего лишь обходной путь, а не решение, которое приятно в мире OSGi:

BundleWiring bundleWiring = context.getBundle().adapt(BundleWiring.class); 
ClassLoader bundleClassLoader = bundleWiring.getClassLoader(); 
Thread currentThread = Thread.currentThread(); 

ClassLoader originalCl = currentThread.getContextClassLoader() 
currentThread.setContectClassLoader(bundleClassLoader); 
try { 
    System.err.println("Shiro : " + ClassUtils.forName("com.firm.demo.MyCustomClass")); 
} finally { 
    currentThread.setContextClassLoader(originalCl); 
} 
+1

+1 Также сообщите об ошибке в отношении Сиро. Библиотеки не должны загружать классы по имени без Classloader, потому что это всегда терпит неудачу в модульной среде. –

+0

Действительно Хорошо! Вы спасете меня после 1-недельного исследования !! Спасибо огромное! Можете ли вы сообщить об ошибке для Сиро, пожалуйста? возможно, это вызов будет полезен для его исправления. – trouble

+0

* (Отправлено новым членом без достаточного ответа, чтобы оставлять комментарии) * @TomNelson писал (а): У меня была такая же проблема с аналогичным обходным решением, поэтому я сообщил https://issues.apache.org/jira/browse/SHIRO-537 – Leigh

Смежные вопросы