> On 25 Aug 2016, at 08:09, Remo Liechti <[email protected]> wrote:
> 
> 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.


Unless I have misunderstood you, that sounds like two places from which the 
type is loaded: the lib folder of the web application (i.e. the application 
classpath on which the OSGi Framework), and a bundle. That’s almost certainly 
the source of the conflict.


> 
>> 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.


If you are in a bundle you can always get your own BundleContext — you do not 
need it to be supplied by JNDI.


> 
>> 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.


I don’t think that’s true. Declarative Services is just a bundle, so you can 
add it to any OSGi application. Weblogic doesn’t need to support it, or even 
know anything about it.



> 
> 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.

Reply via email to