Question

How OSGi solves the problem1 of casting classes which were loaded from bundles with OSGi custom classloader to classes loaded from rt.jar? Does rt.jar loaded with custom classloader too, instead of system classloader?

UPD1

It appears that i canot load most parts of rt.jar with custom classloader, because of the following code in the ClassLoader.java:

private ProtectionDomain preDefineClass(String name, ProtectionDomain protectionDomain) {
    ...
    if ((name != null) && name.startsWith("java.")) {
        throw new SecurityException("Prohibited package name: " +
        name.substring(0, name.lastIndexOf('.')));
    }
    ...
}

[1] the problem is in the following: classes loaded with different classloaders are treated by jvm as entirely different ones even if their byte-code is exactly the same, so when, for example, we have class rt.jar!/SomeClass and derived it inside of bundle.jar!/SomeClassChild, we cannot cast SomeClassChild to SomeClass if they were loaded by different classloaders.

Was it helpful?

Solution

There is no such problem in Java. Certainly not as stated in the question. It is true that classes with the same name loaded by different classloaders are never treated as the same class, but from this it does not follow that a superclass has to be loaded by the same classloader as a subclass.

Actually since all java.* classes, including Object, come from the bootstrap classloader and no user class in an application is loaded by the bootstrap classloader, it would be impossible to even cast anything to Object, ever, way before OSGi came into the picture.

OTHER TIPS

  • java.* classes are special ... The Java specification requires all classes that start with 'java.' to be loaded from the boot class path for security reasons.
  • Other classes, well packages, from rt.jar are exported by the framework itself. All frameworks have a set of defaults but there are properties that allows you to extend these defaults (org.osgi.framework.system.packages[.extra]). The framework will load classes in these packages either from the classloader that loaded the framework or from the boot class loader based on a launch property.

The magic is that the OSGi framework wires all those packages together in a mesh of classloaders that ensures that each bundle sees a consistent class space free of conflicts even if multiple class loaders can load the same class name. Therefore, class cast exceptions cannot happen in OSGi with proper metadata and without class loading hacks.

If two bundles are bound to different class loaders for the same package name then the OSGi framework ensures that these bundles cannot see each other since they then reside in different class spaces.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top