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