Pax Exam

Native Container should try to isolate the Framework classloader from the system classloader

Details

  • Type: New Feature New Feature
  • Status: Open Open
  • Priority: Major Major
  • Resolution: Unresolved
  • Affects Version/s: 2.0.0-RC4, 2.2.0
  • Fix Version/s: 2.5.0
  • Component/s: Native Test Container
  • Labels:
    None
  • Environment:
    Junit 4.8,
    Maven 3

Description

native container runner starts with a dependency filled system classloader. This leads to hard tracable problems with (mostly hybrid) bundles which using first the system classloader for reflection. E.g. the combination of eclipse link with the corresponding apache aries adapter behave different in a pax exam native container as in a blank felix.

(may be related to PAXEXAM-81)

Issue Links

Activity

Hide
Harald Wellmann added a comment -

It is true that some tests may behave differently or even fail when running in the Native container compared to the Pax Runner container. I had a similar effect in a test with OpenJPA 2.1.0 and Aries JPA 0.3.

This is not necessarily a defect in Pax Exam. When you move from the plain old classpath to modular development with OSGi, you will discover that some libraries break because they mess around with Class.forName() which is a no-go in OSGi and a bad idea anyway.

Similarly, when you move from Pax Runner Container to Native Container, the OSGi framework is no longer running in its own VM, there are some bits of Pax Exam that use the official OSGi FrameworkFactory API to launch an embedded framework. In this scenario, the system classloader necessarily contains some other application classes on top of the OSGi framework classes.

Any OSGi framework should take care to set up boot delegation and the parent classloader for bundle classloaders correctly. Equinox gives you some extra control by means of osgi.* system properties.

But even so, there is no way to protect you from bundles in your system calling ClassLoader.getSystemClassloader() directly and thus bypassing the classloader hierarchy carefully set up by the framework.

This is what happens in Aries JPA 0.3 where the BundleDelegatingClassLoader which should load entity classes from application bundles inadvertently works with parent delegation, using the system classloader as its parent, so if you use your entity classes in your Pax Exam test, they will be loaded from the application classloader and not from the bundle classloader.

This class has been reworked substantially on Aries trunk, so I hope this issue will be fixed with the next Aries JPA release.

Show
Harald Wellmann added a comment - It is true that some tests may behave differently or even fail when running in the Native container compared to the Pax Runner container. I had a similar effect in a test with OpenJPA 2.1.0 and Aries JPA 0.3. This is not necessarily a defect in Pax Exam. When you move from the plain old classpath to modular development with OSGi, you will discover that some libraries break because they mess around with Class.forName() which is a no-go in OSGi and a bad idea anyway. Similarly, when you move from Pax Runner Container to Native Container, the OSGi framework is no longer running in its own VM, there are some bits of Pax Exam that use the official OSGi FrameworkFactory API to launch an embedded framework. In this scenario, the system classloader necessarily contains some other application classes on top of the OSGi framework classes. Any OSGi framework should take care to set up boot delegation and the parent classloader for bundle classloaders correctly. Equinox gives you some extra control by means of osgi.* system properties. But even so, there is no way to protect you from bundles in your system calling ClassLoader.getSystemClassloader() directly and thus bypassing the classloader hierarchy carefully set up by the framework. This is what happens in Aries JPA 0.3 where the BundleDelegatingClassLoader which should load entity classes from application bundles inadvertently works with parent delegation, using the system classloader as its parent, so if you use your entity classes in your Pax Exam test, they will be loaded from the application classloader and not from the bundle classloader. This class has been reworked substantially on Aries trunk, so I hope this issue will be fixed with the next Aries JPA release.
Hide
Marcel Hanser added a comment -

Hi Harald. Sry, sry for my late answer.
Yep i know the problem and i'm with you... but this is a big problem when using the pax exam native container... If i add a new library to my runtime i cannot be sure that my integration test will behave as in a usual started OSGi container, this makes the native container not usable for most of my projects... their should be at least a hint or a warning in the pax exam documentation about this problem.

Show
Marcel Hanser added a comment - Hi Harald. Sry, sry for my late answer. Yep i know the problem and i'm with you... but this is a big problem when using the pax exam native container... If i add a new library to my runtime i cannot be sure that my integration test will behave as in a usual started OSGi container, this makes the native container not usable for most of my projects... their should be at least a hint or a warning in the pax exam documentation about this problem.
Hide
Toni Menzel added a comment -

Quick comment on that:it hast Bern Reporter by peter from neo4j (Fournet peter) as well just before my ovacation.
actially this needs to be addressed using classloader Isolation when setting
up the container. No way around it. Its a common req ment when embeddding osgi in non virgin VMs.
Sorry for brevity,writing from mobile.
Toni

Show
Toni Menzel added a comment - Quick comment on that:it hast Bern Reporter by peter from neo4j (Fournet peter) as well just before my ovacation. actially this needs to be addressed using classloader Isolation when setting up the container. No way around it. Its a common req ment when embeddding osgi in non virgin VMs. Sorry for brevity,writing from mobile. Toni
Hide
Toni Menzel added a comment -

Need to stay away from commenting in jira when not actually seeing what i am typing. Sorry. Hope the point is clear anyway..

Show
Toni Menzel added a comment - Need to stay away from commenting in jira when not actually seeing what i am typing. Sorry. Hope the point is clear anyway..
Hide
Harald Wellmann added a comment -

@Marcel: I've added a section to the Pax Exam FAQ about this:
http://team.ops4j.org/wiki/display/paxexam/FAQ
Thought I'd done so some time ago, but evidently I hadn't

@Toni: I'm not aware of any method to achieve 100 % "classloader isolation". We may try to invoke the FrameworkFactory from a classloader that only sees the framework JAR and has the boot classloader as parent, but even in that case, bundles may break out of this jail by calling ClassLoader.getSystemClassloader(), which is bad practice of course, but I don't think we can prevent that.

Show
Harald Wellmann added a comment - @Marcel: I've added a section to the Pax Exam FAQ about this: http://team.ops4j.org/wiki/display/paxexam/FAQ Thought I'd done so some time ago, but evidently I hadn't @Toni: I'm not aware of any method to achieve 100 % "classloader isolation". We may try to invoke the FrameworkFactory from a classloader that only sees the framework JAR and has the boot classloader as parent, but even in that case, bundles may break out of this jail by calling ClassLoader.getSystemClassloader(), which is bad practice of course, but I don't think we can prevent that.
Hide
Toni Menzel added a comment -

Well, at least one can try tweaking the TCL properly which helps to cut the usual threats. Yes, clients can still break out but its then bad behaviour on purpose. I think its just important to limit the possible pitfalls. Currently NativeContainer does not do anything about it - which is just not enough.

Show
Toni Menzel added a comment - Well, at least one can try tweaking the TCL properly which helps to cut the usual threats. Yes, clients can still break out but its then bad behaviour on purpose. I think its just important to limit the possible pitfalls. Currently NativeContainer does not do anything about it - which is just not enough.
Hide
Harald Wellmann added a comment -

Ok, then I think we all agree: There is no 100 % solution, but we should try to provide as much isolation as we can, which is more than what we're doing now.

The question is, is there a generic approach we can implement in Native Container, or does this depend too much on framework specific configuration options?

E.g. Equinox has options

osgi.frameworkParentClassloader
osgi.contextClassLoaderParent

and by default sets the TCCL to its own ContextLoader (can't remember the exact classname).

With Felix, the TCCL for bundles is just the app classloader.

Show
Harald Wellmann added a comment - Ok, then I think we all agree: There is no 100 % solution, but we should try to provide as much isolation as we can, which is more than what we're doing now. The question is, is there a generic approach we can implement in Native Container, or does this depend too much on framework specific configuration options? E.g. Equinox has options
osgi.frameworkParentClassloader
osgi.contextClassLoaderParent
and by default sets the TCCL to its own ContextLoader (can't remember the exact classname). With Felix, the TCCL for bundles is just the app classloader.

People

Vote (0)
Watch (1)

Dates

  • Created:
    Updated: