You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@felix.apache.org by Marc-Andre Houle <mh...@gmail.com> on 2009/06/18 16:42:33 UTC

Newbie question for ClassCastException

I'm sure I am presently asking a really simple question that have been seen
a thousand times.  But since I don't know where to start with OSGI, I'll ask
the question here in hope that one person would help me.

We need to build a plugin management for a web application running wicket.
It is already running and I would want to include OSGI bundle
extendability.  I want bundles that are added to register as services in
order to give access to some methods.  The bundle is installed in felix
using the FileInstall activator.  I will not paste all the code since I
think the interface and implementation is irrelevant here. (Even if they are
really simple).  The problem come with the fact that I cannot cast the
service received into the interface implemented.  I get a ClassCastException
when trying to use it.

Here is the code at initialization of the web application :
//Make the felix startup here.
        Properties felixProps = new Properties();
        try {

felixProps.load(this.getClass().getResourceAsStream("/felix.properties"));
        } catch(Exception e) {
            logger.warn("Could not load felix properties", e);
        }

        List<BundleActivator> list = new ArrayList<BundleActivator>();

        FileInstall activator = new FileInstall();
        list.add(activator);

        this.panelProvider = new PanelServiceProvider();
        list.add(this.panelProvider);

        felixProps.put(FelixConstants.SYSTEMBUNDLE_ACTIVATORS_PROP, list);
        try {
            this.felix = new Felix(felixProps);
            this.felix.start();
            logger.info("Felix started.");
        } catch(Exception ex) {
            logger.error("Could not load felix", ex);
        }

Here is the code for the PanelServiceProvider class :
public class PanelServiceProvider implements BundleActivator {

    private ServiceTracker serviceTracker;
    public void start(BundleContext context) throws Exception {
        this.serviceTracker = new ServiceTracker(context,
PanelDescriptor.class.getName(), null);
        this.serviceTracker.open();
    }
    public void stop(BundleContext arg0) throws Exception {
        this.serviceTracker.close();
    }

    public List<PanelDescriptor> getAllPanelDescriptor(){
        if(this.serviceTracker != null){
            Object[] services = this.serviceTracker.getServices();
            if(services != null){
                List<PanelDescriptor> panels = new
ArrayList<PanelDescriptor>(services.length);
                for(Object service : services){
                    if(service instanceof PanelDescriptor){
                        panels.add((PanelDescriptor)service);
                    }else{
                        System.out.println("Unknown service : " +
service.getClass().getName());
                        for(Type type :
service.getClass().getGenericInterfaces()){
                            System.out.println("Implementing : " +
type.toString());
                        }
                    }
                }
                return panels;
            }
        }
        return null;
    }
}

And here is the result that I get for invoking this method when I call the
page in the web app :

Installed
c:\java\project\demo-wicket-felix\target\felix\fileinstall\panel1-0.0.1-SNAPSHOT.jar
2009-06-18 10:18:34.544::INFO:  Started SelectChannelConnector@0.0.0.0:8080
[INFO] Started Jetty Server
Unknown service : com.mycompany.panel.PanelDescriptorImpl
Implementing : interface com.mycompany.panel.PanelDescriptor


What that mean is that the serive is loaded, it can be reached, but the
classes does not come from the same classloader.  Now, I'm a little lost as
to what I'm supposed to do in this case.Does anybody have an idea on what I
could do to solve this problem?

If more details is needed (Like the manifest files or the other classes),
let met know and I'll provide them.

Thanks in advance.

Marc-Andre

Re: Newbie question for ClassCastException

Posted by "Richard S. Hall" <he...@ungoverned.org>.
There is no wildcard. You must explicitly declare which packages you 
want to expose from the class path by adding it to that property. By 
default, Felix includes all JRE packages for you, but anything else must 
be specified by you.

-> richard

On 6/18/09 2:53 PM, Marc-Andre Houle wrote:
> Great, this was the problem.  My interface was in the same package as the
> implementation and the maven bundle plugin took the liberty to include the
> interface into the jar.
>
> Thanks for the help, it woked first time when I realized this one and
> changed the package name.  Now, I have a second error that I still don't
> know how to solve regarding the system bundle.
>
> I am trying to make a wicket panel into the bundle and include it into the
> main application.  when the bundle is loaded, it give me this error :
>
> Error while starting bundle:
> /C:/java/project/demo-wicket-felix/target/felix/fileinstall/panel1-0.0.1-SNAPSHOT.jar:
> org.osgi.framework.BundleException: Unresolved constraint in bundle 1:
> package; (&(package=org.apache.wicket.ajax)(version>=1.4.0))
>
> To get ride of it, I entered this line in my properties file :
> org.osgi.framework.system.packages.extra=org.apache.wicket;org.apache.wicket.ajax;
> org.apache.wicket.ajax.markup.html; org.apache.wicket.markup.html.basic;
> org.apache.wicket.markup.html.panel; org.apache.wicket.model; version=1.4.0,
> com.mycompany.panel
>
> The problem that I see with that is that everytime the wicket framework get
> updated or the user use something that is unknown to the server in it's
> packages, the line have to be expended.
>
> Is there a patern that can be used in order to make sure this line include
> everything that the server see.  I don't really expect the exports to
> contain everything, but a wildcard like org.apache.wicket.* could be used
> instead to make it easier to manage.
>
> I hope I'm getting clear.  If any of you need more information, just ask and
> it will be my pleasure to give it back.
>
> Marc-Andre
>
>
> On Thu, Jun 18, 2009 at 11:04 AM, Richard S. Hall<he...@ungoverned.org>wrote:
>
>    
>> If you are creating an embedded instance of Felix and trying to use
>> services from bundles inside of Felix on the outside in your host
>> application, then you have to make sure there is only one copy of the
>> service interface class and everyone is using it. Typically this is done by
>> putting them on the class path and exporting them via the system bundle.
>> Check:
>>
>>
>> http://felix.apache.org/site/apache-felix-framework-launching-and-embedding.html
>>
>> ->  richard
>>
>>
>> On 6/18/09 10:42 AM, Marc-Andre Houle wrote:
>>
>>      
>>> I'm sure I am presently asking a really simple question that have been
>>> seen
>>> a thousand times.  But since I don't know where to start with OSGI, I'll
>>> ask
>>> the question here in hope that one person would help me.
>>>
>>> We need to build a plugin management for a web application running wicket.
>>> It is already running and I would want to include OSGI bundle
>>> extendability.  I want bundles that are added to register as services in
>>> order to give access to some methods.  The bundle is installed in felix
>>> using the FileInstall activator.  I will not paste all the code since I
>>> think the interface and implementation is irrelevant here. (Even if they
>>> are
>>> really simple).  The problem come with the fact that I cannot cast the
>>> service received into the interface implemented.  I get a
>>> ClassCastException
>>> when trying to use it.
>>>
>>> Here is the code at initialization of the web application :
>>> //Make the felix startup here.
>>>          Properties felixProps = new Properties();
>>>          try {
>>>
>>> felixProps.load(this.getClass().getResourceAsStream("/felix.properties"));
>>>          } catch(Exception e) {
>>>              logger.warn("Could not load felix properties", e);
>>>          }
>>>
>>>          List<BundleActivator>   list = new ArrayList<BundleActivator>();
>>>
>>>          FileInstall activator = new FileInstall();
>>>          list.add(activator);
>>>
>>>          this.panelProvider = new PanelServiceProvider();
>>>          list.add(this.panelProvider);
>>>
>>>          felixProps.put(FelixConstants.SYSTEMBUNDLE_ACTIVATORS_PROP, list);
>>>          try {
>>>              this.felix = new Felix(felixProps);
>>>              this.felix.start();
>>>              logger.info("Felix started.");
>>>          } catch(Exception ex) {
>>>              logger.error("Could not load felix", ex);
>>>          }
>>>
>>> Here is the code for the PanelServiceProvider class :
>>> public class PanelServiceProvider implements BundleActivator {
>>>
>>>      private ServiceTracker serviceTracker;
>>>      public void start(BundleContext context) throws Exception {
>>>          this.serviceTracker = new ServiceTracker(context,
>>> PanelDescriptor.class.getName(), null);
>>>          this.serviceTracker.open();
>>>      }
>>>      public void stop(BundleContext arg0) throws Exception {
>>>          this.serviceTracker.close();
>>>      }
>>>
>>>      public List<PanelDescriptor>   getAllPanelDescriptor(){
>>>          if(this.serviceTracker != null){
>>>              Object[] services = this.serviceTracker.getServices();
>>>              if(services != null){
>>>                  List<PanelDescriptor>   panels = new
>>> ArrayList<PanelDescriptor>(services.length);
>>>                  for(Object service : services){
>>>                      if(service instanceof PanelDescriptor){
>>>                          panels.add((PanelDescriptor)service);
>>>                      }else{
>>>                          System.out.println("Unknown service : " +
>>> service.getClass().getName());
>>>                          for(Type type :
>>> service.getClass().getGenericInterfaces()){
>>>                              System.out.println("Implementing : " +
>>> type.toString());
>>>                          }
>>>                      }
>>>                  }
>>>                  return panels;
>>>              }
>>>          }
>>>          return null;
>>>      }
>>> }
>>>
>>> And here is the result that I get for invoking this method when I call the
>>> page in the web app :
>>>
>>> Installed
>>>
>>> c:\java\project\demo-wicket-felix\target\felix\fileinstall\panel1-0.0.1-SNAPSHOT.jar
>>> 2009-06-18 10:18:34.544::INFO:  Started
>>> SelectChannelConnector@0.0.0.0:8080
>>> [INFO] Started Jetty Server
>>> Unknown service : com.mycompany.panel.PanelDescriptorImpl
>>> Implementing : interface com.mycompany.panel.PanelDescriptor
>>>
>>>
>>> What that mean is that the serive is loaded, it can be reached, but the
>>> classes does not come from the same classloader.  Now, I'm a little lost
>>> as
>>> to what I'm supposed to do in this case.Does anybody have an idea on what
>>> I
>>> could do to solve this problem?
>>>
>>> If more details is needed (Like the manifest files or the other classes),
>>> let met know and I'll provide them.
>>>
>>> Thanks in advance.
>>>
>>> Marc-Andre
>>>
>>>
>>>
>>>        
>> ---------------------------------------------------------------------
>> To unsubscribe, e-mail: users-unsubscribe@felix.apache.org
>> For additional commands, e-mail: users-help@felix.apache.org
>>
>>
>>      
>
>    

Re: Newbie question for ClassCastException

Posted by Marc-Andre Houle <mh...@gmail.com>.
Great, this was the problem.  My interface was in the same package as the
implementation and the maven bundle plugin took the liberty to include the
interface into the jar.

Thanks for the help, it woked first time when I realized this one and
changed the package name.  Now, I have a second error that I still don't
know how to solve regarding the system bundle.

I am trying to make a wicket panel into the bundle and include it into the
main application.  when the bundle is loaded, it give me this error :

Error while starting bundle:
/C:/java/project/demo-wicket-felix/target/felix/fileinstall/panel1-0.0.1-SNAPSHOT.jar:
org.osgi.framework.BundleException: Unresolved constraint in bundle 1:
package; (&(package=org.apache.wicket.ajax)(version>=1.4.0))

To get ride of it, I entered this line in my properties file :
org.osgi.framework.system.packages.extra=org.apache.wicket;org.apache.wicket.ajax;
org.apache.wicket.ajax.markup.html; org.apache.wicket.markup.html.basic;
org.apache.wicket.markup.html.panel; org.apache.wicket.model; version=1.4.0,
com.mycompany.panel

The problem that I see with that is that everytime the wicket framework get
updated or the user use something that is unknown to the server in it's
packages, the line have to be expended.

Is there a patern that can be used in order to make sure this line include
everything that the server see.  I don't really expect the exports to
contain everything, but a wildcard like org.apache.wicket.* could be used
instead to make it easier to manage.

I hope I'm getting clear.  If any of you need more information, just ask and
it will be my pleasure to give it back.

Marc-Andre


On Thu, Jun 18, 2009 at 11:04 AM, Richard S. Hall <he...@ungoverned.org>wrote:

> If you are creating an embedded instance of Felix and trying to use
> services from bundles inside of Felix on the outside in your host
> application, then you have to make sure there is only one copy of the
> service interface class and everyone is using it. Typically this is done by
> putting them on the class path and exporting them via the system bundle.
> Check:
>
>
> http://felix.apache.org/site/apache-felix-framework-launching-and-embedding.html
>
> -> richard
>
>
> On 6/18/09 10:42 AM, Marc-Andre Houle wrote:
>
>> I'm sure I am presently asking a really simple question that have been
>> seen
>> a thousand times.  But since I don't know where to start with OSGI, I'll
>> ask
>> the question here in hope that one person would help me.
>>
>> We need to build a plugin management for a web application running wicket.
>> It is already running and I would want to include OSGI bundle
>> extendability.  I want bundles that are added to register as services in
>> order to give access to some methods.  The bundle is installed in felix
>> using the FileInstall activator.  I will not paste all the code since I
>> think the interface and implementation is irrelevant here. (Even if they
>> are
>> really simple).  The problem come with the fact that I cannot cast the
>> service received into the interface implemented.  I get a
>> ClassCastException
>> when trying to use it.
>>
>> Here is the code at initialization of the web application :
>> //Make the felix startup here.
>>         Properties felixProps = new Properties();
>>         try {
>>
>> felixProps.load(this.getClass().getResourceAsStream("/felix.properties"));
>>         } catch(Exception e) {
>>             logger.warn("Could not load felix properties", e);
>>         }
>>
>>         List<BundleActivator>  list = new ArrayList<BundleActivator>();
>>
>>         FileInstall activator = new FileInstall();
>>         list.add(activator);
>>
>>         this.panelProvider = new PanelServiceProvider();
>>         list.add(this.panelProvider);
>>
>>         felixProps.put(FelixConstants.SYSTEMBUNDLE_ACTIVATORS_PROP, list);
>>         try {
>>             this.felix = new Felix(felixProps);
>>             this.felix.start();
>>             logger.info("Felix started.");
>>         } catch(Exception ex) {
>>             logger.error("Could not load felix", ex);
>>         }
>>
>> Here is the code for the PanelServiceProvider class :
>> public class PanelServiceProvider implements BundleActivator {
>>
>>     private ServiceTracker serviceTracker;
>>     public void start(BundleContext context) throws Exception {
>>         this.serviceTracker = new ServiceTracker(context,
>> PanelDescriptor.class.getName(), null);
>>         this.serviceTracker.open();
>>     }
>>     public void stop(BundleContext arg0) throws Exception {
>>         this.serviceTracker.close();
>>     }
>>
>>     public List<PanelDescriptor>  getAllPanelDescriptor(){
>>         if(this.serviceTracker != null){
>>             Object[] services = this.serviceTracker.getServices();
>>             if(services != null){
>>                 List<PanelDescriptor>  panels = new
>> ArrayList<PanelDescriptor>(services.length);
>>                 for(Object service : services){
>>                     if(service instanceof PanelDescriptor){
>>                         panels.add((PanelDescriptor)service);
>>                     }else{
>>                         System.out.println("Unknown service : " +
>> service.getClass().getName());
>>                         for(Type type :
>> service.getClass().getGenericInterfaces()){
>>                             System.out.println("Implementing : " +
>> type.toString());
>>                         }
>>                     }
>>                 }
>>                 return panels;
>>             }
>>         }
>>         return null;
>>     }
>> }
>>
>> And here is the result that I get for invoking this method when I call the
>> page in the web app :
>>
>> Installed
>>
>> c:\java\project\demo-wicket-felix\target\felix\fileinstall\panel1-0.0.1-SNAPSHOT.jar
>> 2009-06-18 10:18:34.544::INFO:  Started
>> SelectChannelConnector@0.0.0.0:8080
>> [INFO] Started Jetty Server
>> Unknown service : com.mycompany.panel.PanelDescriptorImpl
>> Implementing : interface com.mycompany.panel.PanelDescriptor
>>
>>
>> What that mean is that the serive is loaded, it can be reached, but the
>> classes does not come from the same classloader.  Now, I'm a little lost
>> as
>> to what I'm supposed to do in this case.Does anybody have an idea on what
>> I
>> could do to solve this problem?
>>
>> If more details is needed (Like the manifest files or the other classes),
>> let met know and I'll provide them.
>>
>> Thanks in advance.
>>
>> Marc-Andre
>>
>>
>>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: users-unsubscribe@felix.apache.org
> For additional commands, e-mail: users-help@felix.apache.org
>
>

Re: Newbie question for ClassCastException

Posted by "Richard S. Hall" <he...@ungoverned.org>.
If you are creating an embedded instance of Felix and trying to use 
services from bundles inside of Felix on the outside in your host 
application, then you have to make sure there is only one copy of the 
service interface class and everyone is using it. Typically this is done 
by putting them on the class path and exporting them via the system 
bundle. Check:

     
http://felix.apache.org/site/apache-felix-framework-launching-and-embedding.html

-> richard

On 6/18/09 10:42 AM, Marc-Andre Houle wrote:
> I'm sure I am presently asking a really simple question that have been seen
> a thousand times.  But since I don't know where to start with OSGI, I'll ask
> the question here in hope that one person would help me.
>
> We need to build a plugin management for a web application running wicket.
> It is already running and I would want to include OSGI bundle
> extendability.  I want bundles that are added to register as services in
> order to give access to some methods.  The bundle is installed in felix
> using the FileInstall activator.  I will not paste all the code since I
> think the interface and implementation is irrelevant here. (Even if they are
> really simple).  The problem come with the fact that I cannot cast the
> service received into the interface implemented.  I get a ClassCastException
> when trying to use it.
>
> Here is the code at initialization of the web application :
> //Make the felix startup here.
>          Properties felixProps = new Properties();
>          try {
>
> felixProps.load(this.getClass().getResourceAsStream("/felix.properties"));
>          } catch(Exception e) {
>              logger.warn("Could not load felix properties", e);
>          }
>
>          List<BundleActivator>  list = new ArrayList<BundleActivator>();
>
>          FileInstall activator = new FileInstall();
>          list.add(activator);
>
>          this.panelProvider = new PanelServiceProvider();
>          list.add(this.panelProvider);
>
>          felixProps.put(FelixConstants.SYSTEMBUNDLE_ACTIVATORS_PROP, list);
>          try {
>              this.felix = new Felix(felixProps);
>              this.felix.start();
>              logger.info("Felix started.");
>          } catch(Exception ex) {
>              logger.error("Could not load felix", ex);
>          }
>
> Here is the code for the PanelServiceProvider class :
> public class PanelServiceProvider implements BundleActivator {
>
>      private ServiceTracker serviceTracker;
>      public void start(BundleContext context) throws Exception {
>          this.serviceTracker = new ServiceTracker(context,
> PanelDescriptor.class.getName(), null);
>          this.serviceTracker.open();
>      }
>      public void stop(BundleContext arg0) throws Exception {
>          this.serviceTracker.close();
>      }
>
>      public List<PanelDescriptor>  getAllPanelDescriptor(){
>          if(this.serviceTracker != null){
>              Object[] services = this.serviceTracker.getServices();
>              if(services != null){
>                  List<PanelDescriptor>  panels = new
> ArrayList<PanelDescriptor>(services.length);
>                  for(Object service : services){
>                      if(service instanceof PanelDescriptor){
>                          panels.add((PanelDescriptor)service);
>                      }else{
>                          System.out.println("Unknown service : " +
> service.getClass().getName());
>                          for(Type type :
> service.getClass().getGenericInterfaces()){
>                              System.out.println("Implementing : " +
> type.toString());
>                          }
>                      }
>                  }
>                  return panels;
>              }
>          }
>          return null;
>      }
> }
>
> And here is the result that I get for invoking this method when I call the
> page in the web app :
>
> Installed
> c:\java\project\demo-wicket-felix\target\felix\fileinstall\panel1-0.0.1-SNAPSHOT.jar
> 2009-06-18 10:18:34.544::INFO:  Started SelectChannelConnector@0.0.0.0:8080
> [INFO] Started Jetty Server
> Unknown service : com.mycompany.panel.PanelDescriptorImpl
> Implementing : interface com.mycompany.panel.PanelDescriptor
>
>
> What that mean is that the serive is loaded, it can be reached, but the
> classes does not come from the same classloader.  Now, I'm a little lost as
> to what I'm supposed to do in this case.Does anybody have an idea on what I
> could do to solve this problem?
>
> If more details is needed (Like the manifest files or the other classes),
> let met know and I'll provide them.
>
> Thanks in advance.
>
> Marc-Andre
>
>    

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@felix.apache.org
For additional commands, e-mail: users-help@felix.apache.org