4 Replies Latest reply on Mar 31, 2012 1:04 AM by ffang

    IllegalArgumentException: object is not an instance of declaring class

    timgstewart

      I might be losing my mind.  I'm getting a strange problem deploying a camel bundle which depends on a public API bundle, and accesses services implementing those APIs from a service bundle.

       

      If anyone recognizes the error or the problem immediately I'd appreicate some feedback, otherwise I might be digging at this for a while.

       

      The problem boils down to a java.lang.IllegalArgumentException: object is not an instance of declaring class on the init() method of the camel bundle's processor bean where the OSGI service defined in the API bundle and implemented in the services bundle is accessed.

       

      Here is the relevant information.  Sorry it is a bit complex, but I hope its clear enough.

       

      The problem occurs deploying the camel bundle, nothing is actually being triggered beyond the init-method on my processor bean which is basically just a validation test that I can hit the service.

       

      This did work on 01-06, but now I'm getting the issue on the 01-06 and the 01-11 versions.  Maybe its something I've done, or maybe something weird being cached, or maybe something else entirely.

       

      I have a bundle which defines the public API for a number of OSGI services meant to be deployed to the bus.  I have a simple service:

       

      AuthenticateService.java

      package com.company.api.auth

       

      public interface AuthenticateService {

          public boolean authenticateSource(String sourceId, String sourcePass);

      }

       

      And its pom does the following:

       

      pom.xml in API bundle

                   

       

      With the api, there is no blueprint.xml.

       

      Then I have an implementation bundle with a simple stub implementing class:

       

      AuthenticateServiceImpl.java

       

      package com.company.services.auth;

       

      import com.company.api.auth.AuthenticateService;

       

      public class AuthenticateServiceImpl implements AuthenticateService {

       

          @Override

          public boolean authenticateSource(String sourceId, String sourcePass) {

              return (sourceId!=null && sourceId.equalsIgnoreCase("stewartt"));

          }

           

      }

       

      Its blueprint.xml declares a service like so:

       

           

       

      My init method is where the failure occurs, which I just added to make sure things started up properly.  Here is the processor code, ignoring the parts where I'm extracting XML:

       

       

      package com.company.camel;

       

      // other imports

      import com.company.api.auth.AuthenticateService;

       

      /**

      *

       

      • @author stewartt

      */

      public class AuthenticationCredentialsProcessor implements Processor {

       

          @Override

          public void process(final Exchange exchange)  {

              // extract XML and call the authenticate service in here exactly like the init method

          }

           

          private AuthenticateService authService = null;

       

          public AuthenticateService getAuthService() {

              return authService;

          }

           

          public void setAuthService(AuthenticateService authService) {

              this.authService = authService;

          }

           

          public void init() {

              System.out.println("OSGi client started.");

              if (authService != null) {

                  System.out.println("Auth on stewartt: "+authService.authenticateSource("stewartt", "stewartt"));

                  System.out.println("Auth on someoneelse: "+authService.authenticateSource("someoneelse", "someoneelse"));

              }

          }

      }

       

      The bundle has a pom.xml that does an Import-Package on *, which creates the dependency on the API bundle.

       

      Now whenever I deploy this camel bundle, I get:

       

       

      16:44:31,625 | ERROR | rint Extender: 3 | BlueprintContainerImpl           | 10 - org.apache.aries.blueprint - 0.3.1 | Unable to start blueprint container for bundle inventory-routes

      org.osgi.service.blueprint.container.ComponentDefinitionException: Unable to intialize bean authenticationProcessor

           at org.apache.aries.blueprint.container.BeanRecipe.runBeanProcInit(BeanRecipe.java:638)[10:org.apache.aries.blueprint:0.3.1]

           at org.apache.aries.blueprint.container.BeanRecipe.internalCreate(BeanRecipe.java:724)[10:org.apache.aries.blueprint:0.3.1]

           at org.apache.aries.blueprint.di.AbstractRecipe.create(AbstractRecipe.java:64)[10:org.apache.aries.blueprint:0.3.1]

           at org.apache.aries.blueprint.container.BlueprintRepository.createInstances(BlueprintRepository.java:219)[10:org.apache.aries.blueprint:0.3.1]

           at org.apache.aries.blueprint.container.BlueprintRepository.createAll(BlueprintRepository.java:147)[10:org.apache.aries.blueprint:0.3.1]

           at org.apache.aries.blueprint.container.BlueprintContainerImpl.instantiateEagerComponents(BlueprintContainerImpl.java:640)[10:org.apache.aries.blueprint:0.3.1]

           at org.apache.aries.blueprint.container.BlueprintContainerImpl.doRun(BlueprintContainerImpl.java:331)[10:org.apache.aries.blueprint:0.3.1]

           at org.apache.aries.blueprint.container.BlueprintContainerImpl.run(BlueprintContainerImpl.java:227)[10:org.apache.aries.blueprint:0.3.1]

           at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:441)[:1.6.0_29]

           at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:303)[:1.6.0_29]

           at java.util.concurrent.FutureTask.run(FutureTask.java:138)[:1.6.0_29]

           at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$301(ScheduledThreadPoolExecutor.java:98)[:1.6.0_29]

           at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:206)[:1.6.0_29]

           at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)[:1.6.0_29]

           at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)[:1.6.0_29]

           at java.lang.Thread.run(Thread.java:662)[:1.6.0_29]

      Caused by: java.lang.IllegalArgumentException: object is not an instance of declaring class

           at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)[:1.6.0_29]

           at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)[:1.6.0_29]

           at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)[:1.6.0_29]

           at java.lang.reflect.Method.invoke(Method.java:597)[:1.6.0_29]

           at org.apache.aries.proxy.impl.ProxyHandler$1.invoke(ProxyHandler.java:50)

           at org.apache.aries.proxy.impl.DefaultWrapper.invoke(DefaultWrapper.java:31)

           at org.apache.aries.proxy.impl.ProxyHandler.invoke(ProxyHandler.java:78)

           at $Proxy79.authenticateSource(Unknown Source)

           at com.company.camel.AuthenticationCredentialsProcessor.init(AuthenticationCredentialsProcessor.java:88)

           at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)[:1.6.0_29]

           at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)[:1.6.0_29]

           at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)[:1.6.0_29]

           at java.lang.reflect.Method.invoke(Method.java:597)[:1.6.0_29]

           at org.apache.aries.blueprint.utils.ReflectionUtils.invoke(ReflectionUtils.java:226)[10:org.apache.aries.blueprint:0.3.1]

           at org.apache.aries.blueprint.container.BeanRecipe.invoke(BeanRecipe.java:824)[10:org.apache.aries.blueprint:0.3.1]

           at org.apache.aries.blueprint.container.BeanRecipe.runBeanProcInit(BeanRecipe.java:636)[10:org.apache.aries.blueprint:0.3.1]

           ... 15 more

        • 1. Re: IllegalArgumentException: object is not an instance of declaring class
          ffang

          Hi,

           

          I think the problem is that your impl bundle has

          <Import-Package>*;resolution:=optional</Import-Package>

          which means it may resolved before the api bundle, so that the package com.company.api.auth may not available for the impl bundle.

           

          You can remove resolution:=optional here and test it again, as the api package com.company.api.auth isn't optional at all for the  impl bundle

           

          Freeman

          • 2. Re: IllegalArgumentException: object is not an instance of declaring class
            sanre6

            the same error is bugging me as well ,removing  resolution=optional does not help . the service interface is available to the impl class before invoking any method on it . Still the error pops up , i think its something to do with the version of blueprint bundle

            • 3. Re: IllegalArgumentException: object is not an instance of declaring class
              sanre6

              This exception usually happens when you are sending a class over the ESB i.e communicating between the bundles . Either as service parameter's or as return type . This is expected OSGI behaviour , since osgi sits on top of java package naming structure to support different versions of same class file .

               

              Ex: lets say we have a class com.ms.test.Hello in bundle A with version 1.0

               

               

              Bundle class loader will assign it as (Bundle A).(1.0).(com.ms.test.Hello)

               

               

              and you have the same class in Bundle B with version 1.0  then it will be  

               

              intepreted by osgi as   (Bundle B).(1.0).(com.ms.test.Hello)

               

               

               

              So if you try to send this class over from bundle A to B and cast it you will face object is not an instance of declaring class exception .  Either use a seperate Helper bundle in which you put the commonly used across classes or keep a single copy of class in one Bundle and make the other bundle dependent on the other package . Hope this helps

              • 4. Re: IllegalArgumentException: object is not an instance of declaring class
                ffang

                Hi,

                 

                Thanks for sharing what you found. Yeah, it's something caused by same class get loaded by different classloaders, it's a common issue in OSGi world,  so the solution as you already discovered, you really shouldn't keep multiple copy of same class in different bundles.

                 

                Freeman