Reputation: 9
I am trying to understand how exactly an OSGi runtime would resolve multiple versions of a dependency at runtime. For this purpose I have set up a simple two-scenario example with outcomes that do not make sense to me.
Suppose we have an App Bundle that directly depends on two libraries.
An important detail is that the HTTP client internally also depends on Gson, but with version B. (Call this bundle B)
Assume Gson Version A and Gson Version B expose identical APIs but have different implementations.
The app bundle code looks like this:
public class Client {
public static void someMethod() {
// This class should come from Gson Version A?
JsonObject a = new JsonObject();
a.addProperty("hello", "world");
HttpClient http = new HttpClient();
// Signature HttpClient::send(String, JsonObject);
// Is this still valid, even though the argument type is from Gson Version A
// while the method definition requires the type from Gson Version B?
http.send("some url", a);
}
}
I have tried two experimental setups. In the first one, I define the HTTP client bundle's dependency to Gson Version B using Import-Package
in the MANIFEST:
Import-Package: com.google.gson;version="2.10.0";
It turns out that this works fine without any LinkageErrors
or ClastCastExceptions
. (why?)
In the second setup, I embedded the Gson Version B JAR directly in Bundle B without any Import-Package
declarations. This results in a loader constraint violation
error at runtime.
I know that in OSGi every bundle has its own class loader which it uses for dependencies on the bundle runtime classpath (given that there is no Import-Package
declaration for the same package name), while imported packages get resolved by the provider bundle's class loader. So, in scenario 1, Bundle C will use the class loader of Bundle B to load Gson Version B. In scenario 2, Bundle C will use its own class loader to load Gson Version B.
I don't exactly see the reasons for why the behavior is different. (no error vs. error)
Upvotes: 0
Views: 56