On 20/04/07, VALLEE Mathieu RD-TECH-GRE
<[EMAIL PROTECTED]> wrote:
I agree with Giovanni that this could be useful to many people. and therefore 
worth investigating. Some time ago, I was also interested in using Jade from 
OSGi bundles. I don't think my solution can be integrated as is in Jade, but I 
describe shortly in case you are interested.

Here is what I did :
1. I defined 2 interfaces :
public interface AgentFactory {
        public Agent createAgent();
}
public interface GenericAgentFactory {
        public void createAgent(String name, String className);
}

2. for each of the agents classes I wanted to use, I created a bundle which:
- contains the code of the agent
- registers an "AgentFactory" service, with a property "agent-type={the agent class 
name}"
- when the "createAgent()" method is called, the service returns a new instance 
of the agent.

I'm doing something similar in my demo of Guice (IoC) on OSGi.

IMHO using services to delegate construction to bundles outside of
the core bundle is the way to go (much like the 'whiteboard' pattern).


3. I created a Jade-Core bundle, which :
- creates a new Jade container (using 
Runtime.instance().createAgentContainer()) when it starts
- registers a "GenericAgentFactory" service.
- when the "createAgent(String name, String className)" is called, the service 
does the following:
        1. lookup the "AgentFactory" service with property 
"agent-type=classname"
        2. call the createAgent() method on this "AgentFactory" factory.
        3. load the agent in the container (using acceptNewAgent(String name, 
Agent agent) in ContainerController)

4. When I want to create an agent from a normal (i.e. non Jade) OSGi bundle, I 
do the following
- discover the "GenericAgentFactory" service
- call the "createAgent(String name, String className)" method

The main issue is that if you want agents to create other agents, you have to use the 
"GenericAgentFactory" service inside OSGi (you can not directly ask the AMS to create an 
agent because it will not find the class). Another issue in my implementation is that I did not 
packaged Jade itself as a bundle, but I added it directly to the OSGi platform classpath. This 
enables every "Jade" bundle to access Jade classes without explicitly importing all the 
required packages. This is not good OSGi practice, but this was quicker for me since there are 
quite a lot of packages in Jade and I did not want to bother with defining all the packages I 
needed. Maybe a properly defined Jade bundle and using DynamicImport-package would be a better 
solution.

Another option is to use a custom classloader to bridge the class hiearchies.

For example: in the core bundle, you create a classloader whose parent is
the bundle classloader, but also has an extra member for the client bundle
classloader (discovered by calling getClassLoader on the instance or class
provided by the client).

Then override the findClass method to delegate any framework classes
to the parent loader, and other classes to the client loader - for example:

public class MyFrameworkClassLoader extends ClassLoader {
 private ClassLoader clientLoader;

 public MyFrameworkClassLoader(Class clientClazz) {
   super(MyFrameworkClassLoader.class.getClassLoader());
   clientLoader = clientClazz.getClassLoader();
 }

 protected Class findClass(String name) throws ClassNotFoundException {
   if (null == clientLoader || name.startsWith("my.framework.package.")) {
     return super.findClass(name);
   } else {
     return clientLoader.loadClass(name);
   }
 }
}

You can use this loader for any code that needs visibility to both framework
and client bundles - most frameworks let you provide classloaders for just
this purpose (for example CGLIB, which is used by Guice).

Hope this helps :)


The main advantages are:
- My agents can use OSGi services (which was what I was interested in)
- I can start agents at anytime and from other bundles, not only when the agent 
bundle itself starts
- when developping, I can update an agent, as follows:
        1. modify the code of the agent
        2. recompile and update the corresponding bundle on the OSGI platform
        3. reload the agent in Jade, without restarting anything else.

I didn't investigate too much how I could integrate better with Jade, but at 
the time I also noticed that Jade has some kind of dynamic import system, which 
enables loading jar files at runtime. I don't remember exactly how this was 
done, but maybe it could interesting to enrich this fonctionnality with an OSGi 
support.

Cheers,

Mathieu

> -----Message d'origine-----
> De : [EMAIL PROTECTED]
> [mailto:[EMAIL PROTECTED] De la part de
> Caire Giovanni
> Envoyé : mercredi 18 avril 2007 09:48
> À : Stefano Lenzi; felix-dev@incubator.apache.org;
> [EMAIL PROTECTED]
> Objet : RE: [jade-develop] Felix/OSGi and JADE Second Part
>
> Hi,
>
> If I understoot the problem correctly, the solution could be
> to declare the DynamicImport-package manifest header in the
> bundle that contains the JADE-Core and specify * as its value.
> This should allow the JADE-Core bundle to load classes from
> all exported packages.
> Let me know if this works. In case it does :-), would you be
> interested in making your work available to the community. I
> think it could be useful for many people.
>
> Bye
>
> Giovanni
>
>
>
> -----Original Message-----
> From: [EMAIL PROTECTED]
> [mailto:[EMAIL PROTECTED] On Behalf Of
> Stefano Lenzi
> Sent: martedì 17 aprile 2007 18.55
> To: felix-dev@incubator.apache.org; [EMAIL PROTECTED]
> Subject: [jade-develop] Felix/OSGi and JADE Second Part
>
> Hi All,
>       I had a chance to clarify my idea and to do more tests.
> Here is what I got and I hope that you can help me to find a solution.
>
>       GOAL: The Goal is to run JADE over OSGi so that agents
> can be installed as bundle and executed when the bundle starts.
>
>       APPROCH: I have created a JADE-Core bundle that
> contains all the library used by JADE(e.g.: core, toosl and
> MTPs). Then I have created a JADE-Example bundle that
> contains all the example that came with JADE and it also
> contains a BundleActivator that during the start method
> executes the setup of the JADE Platform and launches all the
> agent required by the example.
>
>       THE PROBLEM: During the start up of the JADE Platform I
> get the Class Not Found error message that states:
>
> "GRAVE: Cannot create agent Buyer-Alpha: Class
> examples.bookTrading.BookBuyerAgent for agent (
> agent-identifier :name [EMAIL PROTECTED]:1099/JADE ) not found [nested
> java.lang.ClassNotFoundException: *** Class
> 'examples.bookTrading.BookBuyerAgent' was not found because
> bundle 12 does not import 'examples.bookTrading' even though
> bundle 13 does export it. Additionally, the class is also
> available from the system class loader. There are two fixes:
> 1) Add an import for 'examples.bookTrading'
> to bundle 12; imports are necessary for each class directly
> touched by bundle code or indirectly touched, such as super
> classes if their methods are used. 2) Add package
> 'examples.bookTrading' to the
> 'org.osgi.framework.bootdelegation' property; a library or VM
> bug can cause classes to be loaded by the wrong class loader.
> The first approach is preferable for preserving modularity. ***]"
>
>       DEPLOY AND RUNTIME INFORMATION: As you already know I
> have 2 bundles:
> JADE-Core and JADE-Examples. The former contains the Boot
> class that is the class in charge of the startup of the JADE
> platform, the latter contains some of the Agent that I want
> to run on the JADE Platform.
> JADE-Examples imports all the packages exported by JADE-Core,
> thus the Boot class. But during the JADE Platform startup
> (made by Boot and other
> classes) the method Class.loadForName() is invoked and it
> returns the the above error.
>
>       TIP or IDEA?
>
> Stefano "Kismet" Lenzi
>
> P.S.: Sorry for the long post... If you want I can give you
> more details...
> P.P.S.: It's my first Class Loading headache :S
> P.P.P.S.: As you can see I have cross posted the message to
> Felix and JADE _______________________________________________
> jade-develop mailing list
> [EMAIL PROTECTED]
> https://avalon.cselt.it/mailman/listinfo/jade-develop
> UNSUBSCRIBE INSTRUCTIONS AT
> http://jade.tilab.com/community-mailinglist.htm
> _______________________________________________
> jade-develop mailing list
> [EMAIL PROTECTED]
> https://avalon.cselt.it/mailman/listinfo/jade-develop
> UNSUBSCRIBE INSTRUCTIONS AT
> http://jade.tilab.com/community-mailinglist.htm
>



--
Cheers, Stuart

Reply via email to