Hi Neil
Thanks for answering. The point is I can make limited changes to the existing
application only.
Basically I created my own main bundle activator that registers the services
again that previously were created using regular osgi.
What the activator is doing:
- Configure bundles using the ConfigurationAdmin
- the configured bundles expose their services itself within osgi. I cannot
access them outside the main activator.
- due to this, re-register the services again in the main activator, since
weblogic classloader would throw classcast Class A to Class A when not doing it
Code of the main activator more or less:
public void start(BundleContext context) throws IOException
ConfigurationAdmin configAdmin = getConfigurationAdminService(context);
configAdmin.getConfiguration("com.kuka.task.manager.component",
null).update(getTaskManagerConfiguration());
ServiceReference<?> ref =
context.getServiceReference(IExtendedTaskManager.class);
Object service = context.getService(ref);
context.registerService(IExtendedTaskManager.class.getName(), service,
properties);
After that, the web application can access the task manager service from j2ee.
The @Resource annotation injects the main activator bundle into the web
application (see
https://docs.oracle.com/middleware/1212/wls/WLPRG/osgi.htm#WLPRG778). It
basically is a JNDI lookup.
You tell the Weblogic container what application to inject like this:
https://docs.oracle.com/middleware/1212/wls/WLPRG/osgi.htm#WLPRG765 Example
16-4 Adding the Framework and Bundle to weblogic-application.xml
The class that causes the Linkage Error is not in multiple jar files, it is
within the com.kuka.nav.api bundle. It's there once only, and the jar file is
also just once in the lib folder of the web application only.
> 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
Well I do not have much of a choice since Weblogic just passes it to me using
the @Ressource.
> 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.
You are right, a point for improvement. I will change this.
> This code would be much better if written as a Declarative Service component
> with injection of the service using an @Reference annotation.
Unfortunately, this is not supported by Weblogic OSGI to webapplications. This
would work within the main activator only, where we cannot put the business
logic/api calls.
Thanks,
Remo
> -----Original Message-----
> From: Neil Bartlett [mailto:[email protected]]
> Sent: Donnerstag, 25. August 2016 08:41
> To: [email protected]
> Subject: Re: LinkageError, but why?
>
>
> > On 25 Aug 2016, at 07:23, Remo Liechti <[email protected]> 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 fine.
> > 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(Fl
> > eetSimulationImpl.java:137) at
> > com.kuka.nav.fleet.simulation.internal.FleetSimulationImpl.addRobot(Fl
> > eetSimulationImpl.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.cl
> > ass);
> > 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 instead:
> > 69: IResourceManager resMan = getService(IResourceManager.class);
> > 70: FleetSimulation simulation = (FleetSimulation)
> > resMan.getResource("FleetSimulation").getCapability(FleetSimulation.cl
> > ass);
> > 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(serviceInt
> erface));
> > }
>
>
> 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.
>
> Regards,
> Neil
>
> >
> >
> > Any idea what can be done to solve the linkage error? Maybe any Devs out
> there of felix itself?
> >
> > 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.
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.