Source: http://www.blogjava.net/BlueDavy/archive/2009/04/24/267425.htmlWhen using OSGi, there are times when you need to get OSGi services outside of the OSGi container, load the class that the OSGi container loads, or you need to embed an OSGi container, and this blog is a simple example of how to implement the embedded OSGi container based on Equinox, or by using the program to start the Equinox, it also shows how to get OSGi services outside the container and to load the class of other plug-ins inside the OSGi container, along with a way to get the plug-ins in the OSGi container to load into classes outside of the OSGi container.
For those of you who have used Equinox, or who have seen my two examples of OSGi OpenDoc, you will know how to start the Equinox from the command line, a common script: Java-jar plugins/ Org.eclipse.osgi_3.2.1.r32x_v20060919.jar-configuration Configuration-console, A config.ini is then placed in the configuration directory of the current directory, where the plug-ins that need to be loaded and started are configured by osgi.bundles= in this config.ini, such as Osgi.bundles=a.jar@start, Then in the program to start the Equinox container, in fact, basically is similar.
View the Equinox Code, You will see the static run method in Eclipestarter after the Org.eclipse.osgi.jar is invoked, so just pass in the appropriate parameters externally and call this run method to complete the Equinox startup, start the Equinox in the program, and usually want to be able to specify Config.ini configuration information and the location of the plug-in, instead of being determined by the Equinox, by default eclipsestarter will generate configuration under the work path and configuration in the Config.ini directory as Equinox Boot Configuration, For the path to the bundle of the Osgi.bundles configuration, the default is the directory where the current Eclipsestarter code is located, such as the command line above, Equinox to load the plug-in from the plugins directory at startup, which is usually not able to meet the need to start the equinox in the program, such as To customize the configuration information for Equinox startup, Instead of loading the config.ini in the specified configuration, you can call Frameworkproperties.setproperty in your program to set the configuration information for the startup equinox, such as the loaded B specified in the osgi.bundles that you want to specify The relative path of the Undle, you can add the Osgi.syspath designation in the Equinox configuration information, Frameworkproperties.setproperty ("Osgi.syspath", You want to specify the path of the bundle, there are many kinds of Equinox boot configuration information, if necessary, you can view the ProcessCommandLine method in Eclipsestarter, after this way, You can start the Equinox:EclipseStarter.run (new string[]{"-console"},null) in a similar way, and you can start equinox in an external program in the way that it does.
OSGi obtains the OSGi service through Bundlecontext, so the first problem in getting OSGi services outside of the OSGi container is to get the bundlecontext out of the OSGi container first, Eclipsestarter provides a Getsystembundlecontext method that allows easy access to bundlecontext, while Bundlecontext can easily get an example of an OSGi service, However, it should be noted at this point that it is not very good to perform the method of this OSGi service instance, because the ClassLoader outside the container is not the same as the classloader of the OSGi service instance's class. So it's not very good to invoke it directly in the way Java objects do, but it's more plausible to call it by reflection.
If you want to get the class of plug-ins in the OSGi container outside of the container, an alternative approach is to get the bundle by Bundlecontext, and then load the class by bundle, and the class that is loaded with this method guarantees that it is the same. Otherwise, a a.class outside the container will not be equal to the a.class of the plug-in in the container, which is understandable for people who know a little bit about the Java ClassLoader mechanism.
According to the above, a simple startup equinox and a class that interacts with the OSGi container can write this:
Code highlighting produced by Actipro Codehighlighter (freeware)
http://www.CodeHighlighter.com/
-->/**
* Start and run the Equinox container
*/
public static void Start () throws exception{
Assemble a osgibundles string similar to the A.jar@start,b.jar@3:start format, as needed to load the bundle to
String osgibundles = "";
Configure Equinox to start
Frameworkproperties.setproperty ("Osgi.noshutdown", "true");
Frameworkproperties.setproperty ("Eclipse.ignoreapp", "true");
Frameworkproperties.setproperty ("Osgi.bundles.defaultStartLevel", "4");
Frameworkproperties.setproperty ("Osgi.bundles", osgibundlesbuilder.tostring ());
Set the path to bundle as needed
String Bundlepath = "";
Specifies the directory where the plugins is to be loaded
Frameworkproperties.setproperty ("Osgi.syspath", Bundlepath);
Call Eclipsestarter, complete the start of the container, and specify the configuration directory
Eclipsestarter.run (New string[]{"-configuration", "Configuration", "-console"}, NULL);
Get to Bundlecontext via Eclipestarter
context = Eclipsestarter.getsystembundlecontext ();
}
/**
* Obtain the OSGi service from the Equinox container instance can also be used to further address the situation of the multi-service interface implementation
*
* @param serviceName Service Name (Full interface class name)
*
* @return Object returns NULL when the corresponding service is not found
*/
public static Object Getosgiservice (String serviceName) {
ServiceReference serviceref = context.getservicereference (serviceName);
if (serviceref = null)
return null;
Return Context.getservice (SERVICEREF);
}
/**
* Get the class of plug-ins in the OSGi container
*/
public static Class <?> getbundleclass (String bundlename,string className) throws exception{
Bundle[] bundles = context.getbundles ();
for (int i = 0; i < bundles.length i + +) {
if (Bundlename.equalsignorecase (Bundles[i].getsymbolicname ())) {
Return Bundles[i].loadclass (ClassName);
}
}
}
After implementing an OSGi container outside of OSGi, it is common to create a requirement that a plug-in inside an OSGI container will load a class outside of the OSGi container, such as an MVC container that is provided within the OSGi containers, and the action class is loaded by other containers outside the OSGi container. So this is the time to have this demand, and in order to do this, there is a relatively simple solution, is to write a bundle, in the bundle to allow the setting of an external classloader OSGi services, such as:
public class classloaderservice{
public void Setclassloader (ClassLoader ClassLoader);
}
Then, based on the above method, the Setclassloader method that performs classloaderservice this OSGi service is reflected in the externally initiated Equinox class, and the external ClassLoader is set in. This classloaderservice is then invoked to complete the loading of the class when a class outside the OSGi container needs to be loaded in the OSGi container's plug-in.
Based on these methods, it is basically possible to achieve a better integration of OSGi containers with other containers, such as starting OSGi in Tomcat, and so on, but this is not as good as being dynamic, unless the external container can provide the corresponding dynamic mechanism. Specifically in the next blog in detail to discuss the dynamic of OSGi.
The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion;
products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the
content of the page makes you feel confusing, please write us an email, we will handle the problem
within 5 days after receiving your email.
If you find any instances of plagiarism from the community, please send an email to:
info-contact@alibabacloud.com
and provide relevant evidence. A staff member will contact you within 5 working days.