0

I have a Virgo-Tomcat-Server running. There is an EnumMap, whose key is

bundle.a.MyEnum

Context from this map is received via

bundle.b

and Spring expression language using a SpelExpressionParser, a sample expression would be "get(T(bundle.a.MyEnum).SAMPLEKEY)". The Parser (respectively its TypeLocator) needs access to the ClassLoader of bundle.a.

So I did:

TypeLocator typeLocator = new StandardTypeLocator(getBundleAClassLoader());
StandardEvaluationContext evaluationContext  = new StandardEvaluationContext();
evaluationContext.setTypeLocator(typeLocator);
spelExpressionParser = new SpelExpressionParser();
spelExpressionParser.parseExpression(expression)).getValue(evaluationContext, context);

The question is, what is the proper way to get the class loader of bundle.a in a class of bundle.b? After a couple of attempts, the only working solution I found is:

private static ClassLoader getBundleAClassLoader() {
    MyEnum bundleARef = MyEnum.SAMPLEKEY;
    return bundleARef.getClass().getClassLoader();
}

Edit: Solution

getBundleAClassLoader()

is not necessary,

TypeLocator typeLocator = new StandardTypeLocator(this.getClass().getClassLoader());

works fine.

pma
  • 860
  • 1
  • 9
  • 26

2 Answers2

1

This sounds too complicated. Just do an Import-Package in the Manifest of bundle.b and you can access the type in the same way as your own type.

Christian Schneider
  • 19,420
  • 2
  • 39
  • 64
  • bundle.b imports bundle.a, but without the StandardEvaluationContext, the Spring-class SpelParserExpression will use the ClassLoader of bundle.b resulting in a ClassNotFoundException – pma Feb 21 '17 at 12:11
  • If bundle.b imports the package of MyEnum then the classloader of bundle.b will find the the class bundkle.a.MyEnum – Christian Schneider Feb 21 '17 at 12:40
  • I stand corrected, it works. Guess I had the TypeLocator not yet set correctly when I tried this.getClass().getClassLoader(). Thanks! – pma Feb 21 '17 at 14:51
1

e.g.

SomeClassOfBundle.class.getClassLoader()

or

bundle.adapt(BundleWiring.class).getClassLoader()
Puce
  • 37,247
  • 13
  • 80
  • 152
  • I have tried the first suggestion and it did not work. I have also tried the second, with Bundle b = bundleContext.getBundle() which would result in bundle.b and hence in its ClassLoader. Probably I should use getBundles() instead and getting the right one. – pma Feb 21 '17 at 12:16
  • What do you mean with "did not work"? A bundle-wiring error? You need to have an Import-Package in the Manifest file for the package of SomeClassOfBundle if you want to use the first approach. – Puce Feb 21 '17 at 12:30
  • I'm positive I had the first approach tested yesterday and received a ClassNotFoundException. However, I tested it again and it worked. Since Christians answer lead me to this.getClass().getClassLoader() I accepted his answer, but thank you nonetheless. – pma Feb 21 '17 at 14:55