You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@felix.apache.org by "Richard S. Hall" <he...@ungoverned.org> on 2007/06/22 15:00:42 UTC

Re: Embedding Felix in JBoss

Todd Nist wrote:
> Richard,
>
> Thanks for the follow up and clarification on the two configuration
> properties.  I like the modularity of OSGi and the enforcement of
> defining the precise dependencies.  
>
> The thing that really confused me was when I went to boot delegation,
> and removed the explicit imports, the bundles still complained about not
> being able to find the classes in question; I guess I must have missed
> something somewhere :(
>   

We'd have to investigate it, but if you boot delegate it should 
definitely happen automatically with no imports in the bundles.

> The only thing I do not like about my current solution is that there
> will be 50 or more packages from our application that I need to add to
> the org.osgi.framework.system.packages property.  As new packages are
> added this will have to be updated and seems rather error prone.  Is
> there any easy way to manage this that you can think of? 
>   

Not really. If you think about your application as if it were a module 
itself, it would need to explicitly declare its exports too, i.e., all 
bundles must explicitly list their exports since there is no way to 
guess what they want to expose. Imports do not have this issue since 
tools like BND can pretty accurately determine what a bundle must 
import. Tools like mangen make attempts to guess proper exports, this 
will not work in all cases since it operates on a "closed world" assumption.

> In the ideal world, the EJB container would be nothing more than a
> bundle that is deployed on top of an OSGi container and would expose the
> bundle exports appropriately; something along the lines of the EasyBeans
> implementation.  I guess I could hook the deployer in the application
> server and read the manifest.mf, determine if it is a bundle, and if so
> pass the exported packages over to Felix.  If I were to do this, is
> there a way to tell Felix to add these exports to the
> org.osgi.framework.system.packages?
>   

I am not sure what you are asking. Are you talking about dynamically 
modifying the system packages property or just configuring it? Your 
example below already shows how to configure it.

I think you have hit upon the correct approach. Somehow you need to 
define a way in which your application declares its exports. Then when 
you go to launch Felix you probe to find the application's export 
meta-data and add this to the system packages property when starting Felix.

> So for now, I will look at how to manage the population of the
> org.osgi.framework.system.packages property in some automated fashion.
> If you have any ideas on this one, they are appreciated.
>   

Not really...just add some meta-data that can be discovered from the 
application.

-> richard

> Again, thanks for the reply and clarifications.
>
> Regards,
> Todd
>  
> -----Original Message-----
> From: Richard S.Hall [mailto:heavy@ungoverned.org] 
> Sent: Thursday, June 21, 2007 5:15 PM
> To: dev@felix.apache.org
> Subject: Re: Embedding Felix in JBoss 
>
> I won't claim to totally understand your scenario, but if your bundles  
> are using external packages, then the bundle must import them.
>
> Also, it is worthwhile to understand the distinction between the two  
> configuration properties for dealing with class path packages:
>
> org.osgi.framework.system.packages - this lists packages from the class
>
> path that the system bundle should export so that bundles can import  
> them.
>
> org.osgi.framework.bootdelegation - this lists packages from the class  
> path that bundles will automatically be given access to whether they  
> import them or not.
>
> If your bundle explicitly imports the packages, then you must include  
> class path packages on the system packages property, even if you boot  
> delegate them otherwise the bundle will not be able to resolve.  
> However, if you boot delegate a package then the bundle doesn't need to
>
> import the package at all, but this is not the preferred way of doing  
> things since it makes the dependency invisible...of course if you don't
>
> plan on using the bundle separately or on any other framework, then  
> maybe it doesn't matter.
>
> So needless to say, if your bundle explicitly imports packages that are
>
> in the EAR and not exported by other bundles, then you must somehow  
> expose to them the stuff in the EAR that they need. This is what you  
> are doing with the system packages property, you are telling the System
>
> Bundle to offer to export it.
>
> When the System Bundle gets a request for that package it will do  
> something like:
>
>      this.getClass().getClassLoader().loadClass(name);
>
> Which will delegate the class load request to the class loader that  
> loaded the Felix classes, which in your case I guess would be the class
>
> loader responsible for loading stuff from the EAR. Thus everything  
> appears to be wired up correctly.
>
> So, I am not really sure what part you do not like. I think the issue  
> you are seeing is that OSGi modularity forces you to be precise about  
> dependencies, which ultimately is a good thing. If you don't want to be
>
> precise, then you should use boot delegation for packages you don't  
> want to import and then remove these packages from the bundle's  
> imported packages...but this would not be my recommended approach.
>
> -> richard
>
> On Jun 21, 2007, at 4:57 PM, Todd Nist wrote:
>
>   
>> Hi,
>>
>>
>>
>> I am attempting to embed Felix in both JBoss and OC4J and while I am
>> able to get it to work, I am a little confused as to why and I  
>> certainly
>> do not like my current solution.
>>
>>
>>
>> public class FelixOSGiProvider extends OSGiProvider {
>>
>>
>>
>>       /**
>>
>>        * Default Constructor.
>>
>>        */
>>
>>       protected FelixOSGiProvider(){}
>>
>>       /**
>>
>>        * Method to start the underlying OSGi runtime.
>>
>>        * @throws Exception for startup exceptions.
>>
>>        */
>>
>>       public void start() throws Exception {
>>
>>             System.out.println("---Starting up Felix OSGi Container
>> 18---");
>>
>>             // Create a case-insensitive configuration property map.
>>
>>             Map configMap = new StringMap(false);
>>
>>             // Configure the Felix instance to be embedded.
>>
>>             configMap.put(FelixConstants.EMBEDDED_EXECUTION_PROP,
>> "true");
>>
>>             configMap.put(FelixConstants.SERVICE_URLHANDLERS_PROP,
>> "false");
>>
>>             // Add the host provided service interface package and the
>> core OSGi
>>
>>             // packages to be exported from the class path via the
>> system bundle.
>>
>>             configMap.put(Constants.FRAMEWORK_SYSTEMPACKAGES,
>>
>>                         "org.osgi.framework; version=1.3.0,"
>>
>>                         + "org.osgi.service.packageadmin;
>> version=1.2.0,"
>>
>>                         + "org.osgi.service.startlevel;
>>     
> version=1.0.0,"
>   
>>                         + "org.osgi.service.url; version=1.0.0,"
>>
>>                         + "com.leica.osgi.services; version=1.0.0,"
>>
>>                         + "com.leica.osgi.entity; version=1.0.0");
>>
>>             configMap.put(FelixConstants.AUTO_START_PROP +
>>
>>
>> ".1","file:///C:\\workspace\\Leica-OSGi-ServiceImpl- 
>> Bundle\\build\\com.l
>> eica.osgi.serviceImpl.jar ");
>>
>>                 configMap.put(BundleCache.CACHE_PROFILE_DIR_PROP,
>> "c:\\OSGiBundles\\Leica-OSGi-Bundles");
>>
>>             //Put the default Activator,
>>
>>             List<BundleActivator> baseBundles = new ArrayList
>> <BundleActivator>();
>>
>>             baseBundles.add(this.getActivator());
>>
>>             // Now create an instance of the framework.
>>
>>             Felix felix = new Felix();
>>
>>             felix.start(new MutablePropertyResolverImpl(configMap),
>>
>>                         baseBundles);
>>
>>       }
>>
>> }
>>
>>
>>
>> I have an EAR that contains the following .jars:
>>
>>
>>
>>     com.leica.osgi.services.jar (Contains the ServiceAPI - interfaces)
>>
>>     com.leica.osgi.entity.jar (Contains Entities)
>>
>>     framework.jar  (contains class to bootstrap felix)
>>
>>     leica.war (contains a Servlet that creates an instance of the
>>     
> Felix
>   
>> framework by using classes in framework.jar)
>>
>>
>>
>> The only way I could get this to work was to include the
>> "com.leica.osgi.services" and "com.leica.osgi.entity" packages in the
>> FRAMEWORK_SYSTEMPACKAGES property.  The bundle loaded by felix below,
>> com.leica.osgi.serviceImpl.jar, provides an implementation of a simple
>> OSGi Bundle that provides a simple service to getAllUsers().
>>
>>
>>
>> When the application is deployed, the embedded Felix instance is  
>> created
>> by the StartupServlet which binds the BaseBundleActivator to the JNDI
>> tree.  When an EJB is called that is dependent on an OSGi service, it
>> looks up the BaseBundleActivator from the JNDI tree and invokes the
>> appropriate method; in this case, getAllUsers().
>>
>>
>>
>> The OSGi service, is dependent on importing packages from
>> com.leica.osgi.services and com.leica.osgi.entity, which are located
>>     
> in
>   
>> the .ear file.  This has me a bit confused, since these packages are
>> deployed by the .ear how am I finding the classes in my Service?   
>> Should
>> I not get a ClassNotFoundException or some other error?
>>
>>
>>
>> I really to not want to have to include all the packages of the system
>> as part of the FRAMEWORK_SYSTEMPACKAGES.  Ideally, I would prefer that
>> the entities, serviceAPI and ServiceImpl are all bundles and deployed
>> inside the embedded Felix instance and allow the EJB's to access them
>> similar to the above.
>>
>>
>>
>> So I guess my first question is why does this work?
>>
>>
>>
>> Is it possible to remove the additional packages form the
>> FRAMEWORK_SYSTEMPACKAGES and still gain access to them from within the
>> EJB container?  Do I need a custom class loader to support this?
>>
>>
>>
>> Is this even possible?
>>
>>
>>
>> I tried adding the com.leica.* to the FRAMEWORK_BOOTDELEGATION
>>     
> packages
>   
>> and removed the reference to them from the FRAMEWORK_SYSTEMPACKAGES,  
>> but
>> then I got an error that the bundle could not find a required import,
>> com.leica.osgi.entity.
>>
>>
>>
>> Thanks is advance for your assistance.
>>
>>
>>
>> Regards,
>>
>>
>>
>> Todd
>>
>>
>>
>>     
>
>