felix-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Neil Bartlett <njbartl...@gmail.com>
Subject Re: LinkageError, but why?
Date Thu, 25 Aug 2016 06:40:49 GMT

> On 25 Aug 2016, at 07:23, Remo Liechti <remo.liechti@swisslog.com> wrote:
> Hi guys
> I send this to you since this seems like a more technical issue than the felix user mailing
list can help me with.

Not really… folks on that list can handle any level of technicality (they are mostly the
same folks as on this list)!

> I am wrapping an existing osgi application that was running with equinoix into a j2ee
application that runs on Weblogic. After a few issues, the application deploys and run totally
> I can access it sockets and connect the client to it without issues.
> But when it comes to accessing the app using the OSGI Services, I can call a few methods.
However, as soon as I call a method on a service that has non Java-Datatypes, I get LinkageErrors,
like this one:
> java.lang.LinkageError: loader constraint violation: loader (instance of org/apache/felix/framework/BundleWiringImpl$BundleClassLoaderJava5)
previously initiated loading for a different type with name "com/kuka/nav/robot/MobileRobotType"
> at com.kuka.nav.fleet.simulation.internal.FleetSimulationImpl.addRobot(FleetSimulationImpl.java:137)
> at com.kuka.nav.fleet.simulation.internal.FleetSimulationImpl.addRobot(FleetSimulationImpl.java:177)
> at com.swisslog.wm6.test.MoveServlet.processRequest(MoveServlet.java:71)
> at com.swisslog.wm6.test.MoveServlet.doGet(MoveServlet.java:95)
> at javax.servlet.http.HttpServlet.service(HttpServlet.java:731)

LinkageError occurs when a ClassLoader is asked to define a type that has already been defined.
It would be useful for you to read the OSGi R6 Core specification about Class Spaces, i.e.
section 3.5 of OSGi.

In OSGi this usually happens when a type is included as a private package in multiple bundles.
The usual things to look out for are:
1. Which bundle(s) export the package com.kuka.nav.robot? This can include the system bundle
if you are exporting into the framework from outside.
2. Do any bundles contain their own copy of types in that package, including MobileRobotType?
3. How is boot delegation configured in your framework? If this is “*” then it could lead
to conflicts with bundles.

> What I try to achieve is:
> 69: IResourceManager resMan = getService(IResourceManager.class);
> 70: FleetSimulation simulation = (FleetSimulation) resMan.getResource("FleetSimulation").getCapability(FleetSimulation.class);
> 71: simulation.addRobot(new BasicRobotType(7), "Robotinator");
> 72: simulation.startAllRobots();
> As you can see, the type to pass to addRobot is of BasicRobotType.
> We tried with a different method, that instead of a BasicRobotType takes a regular integer
> 69: IResourceManager resMan = getService(IResourceManager.class);
> 70: FleetSimulation simulation = (FleetSimulation) resMan.getResource("FleetSimulation").getCapability(FleetSimulation.class);
> 71: simulation.addRobot(7, "Robotinator");
> 72: simulation.startAllRobots();
> This works fine then. But this also means we would have to change the API significantly
and to a low level API who nobody likes.
> Information about the classes:
> public interface MobileRobotType
> public final class BasicRobotType implements MobileRobotType The java classes are in
a single jar file and are not duplicated on the classpath.
> @Resource(lookup = "java:app/osgi/Bundle") Bundle activatorBundle;
> public <T> T getService(Class<T> serviceInterface) {
>        return activatorBundle.getBundleContext()
>                .getService(activatorBundle.getBundleContext().getServiceReference(serviceInterface));
>    }

I’m not familiar with this @Resource annotation, who defines it and what does it do?

Also the code in the method is dangerous. You should never lookup a service using somebody
else’s BundleContext — this could easily lead to errors since OSGi cannot perform its
class-space integrity checks. Also where is the code in which you release the reference to
the service? You have thrown away the ServiceReference object so I assume you don’t ever
actually release the service.

This code would be much better if written as a Declarative Service component with injection
of the service using an @Reference annotation.


> Any idea what can be done to solve the linkage error? Maybe any Devs out there of felix
> Thanks
> This message may contain legally privileged or confidential information and is therefore
addressed to the named persons only. The recipient should inform the sender and delete this
message, if he/she is not named as addressee. The sender disclaims any and all liability for
the integrity and punctuality of this message. The sender has activated an automatic virus
scanning, but does not guarantee the virus free transmission of this message.

View raw message