Interact with osgi outside the osgi container

Source: Internet
Author: User
Source: bytes.

For those who have used equinox, or who have read the two examples that come with osgi opendoc, they will know how to start equinox through the command line, A common script is: Java-jar plugins/org. eclipse. osgi_3.2.1.r32x_v20060919.jar-configuration-console, and then place a Config under the configuration directory of the current directory. INI, In this config. using osgi. bundles = to configure the plug-ins to be loaded and started, such as osgi. bundles =. jar @ start, the Equinox container should be started in the program, which is basically the same.

Check the Equinox code and you will see the above Org. eclipse. osgi. jar and then execute the static run method in eclipestarter. Therefore, you only need to input an appropriate parameter externally and call this run method to start equinox and start equinox in the program, you usually want to specify config. ini configuration information and plug-in location, rather than determined by Equinox. If you do not set it, eclipsestarter will generate configuration in the working path by default, and use the config. INI is used as the configuration for Equinox startup, for osgi. the bundle path configured by bundles. The default path is the directory where the current eclipsestarter code is located. For example, in the preceding command line, equinox loads the plug-in from the Plugins directory at startup, this is usually unable to meet the needs of starting equinox in the program, if you want to customize equinox Instead of loading the config. INI, you can call frameworkproperties in the program. setproperty to set the configuration information for starting Equinox. If you want to specify osgi. the relative path of the loaded bundle specified in bundles, you can add osgi in the configuration information started by equinox. syspath, frameworkproperties. setproperty ("osgi. syspath ", the path of the bundle you want to specify). There are many other configuration information for Equinox startup. If you need it, you can view the processcommandline method in eclipsestarter, you can start equinox: eclipsestarter in a similar way. run (New String [] {"-console"}, null); Follow the preceding steps You can start equinox in an external program.

Osgi obtains the osgi service through bundlecontext. To obtain the osgi service outside the osgi container, you must first obtain the bundlecontext outside the osgi container, eclipsestarter provides a getsystembundlecontext method, which allows you to easily obtain bundlecontext, and bundlecontext allows you to easily obtain osgi service instances. However, you must note that, if you want to execute the method of this osgi service instance, it is not easy to do, because the classloader outside the container is different from the classloader where the class of the osgi service instance is located, therefore, it is not good to directly call Java objects by reflection.

To obtain the class of the plug-in the osgi container outside the container, an optional method is to obtain the bundle through bundlecontext and then load the class through bundle, the class loaded in this way can be ensured to be the same, otherwise. class is not equal to. class, which is understandable to anyone who knows a little about the Java classloader mechanism.

As mentioned above, a simple class that starts equinox and interacts with osgi containers can be written as follows: /**
* Start and run the Equinox container
*/
Public static void start () throws exception {
// Assemble an osgibundles string similar to A. Jar @ start, B. Jar @ 3: Start according to the bundle to be loaded.
String osgibundles = "";
// Configure equinox startup
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 of the bundle as needed
String bundlepath = "";
// Specify the directory of the Plugins to be loaded
Frameworkproperties. setproperty ("osgi. syspath", bundlepath );
// Call eclipsestarter to start the container and specify the configuration directory
Eclipsestarter. Run (New String [] {"-configuration", "configuration", "-console"}, null );
// Get bundlecontext through javasestarter
Context = eclipsestarter. getsystembundlecontext ();
}

/**
* Stop the Equinox container
*/
Public static void stop (){
Try {
Eclipsestarter. Shutdown ();
Context = NULL;
}
Catch (exception e ){
System. Err. println ("error occurred when stopping the Equinox container:" + E );
E. printstacktrace ();
}
}

/**
* Obtaining the osgi service instance from the Equinox container can also further process the implementation of multiple service interfaces based on this
*
* @ Param servicename service name (full interface class name)
*
* @ Return object: if the corresponding service is not found, null is returned.
*/
Public static object getosgiservice (string servicename ){
Servicereference serviceref = context. getservicereference (servicename );
If (serviceref = NULL)
Return NULL;
Return context. getservice (serviceref );
}

/**
* Obtain the classes of the 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. inclusignorecase (bundles [I]. getsymbolicname ())){
Return bundles [I]. loadclass (classname );
}
}
}

After the osgi container and osgi interaction are realized, a requirement is usually generated at the same time, that is, the plug-in the osgi container needs to load classes outside the osgi container, for example, an MVC framework is provided in the osgi container, and the action class is loaded by other containers outside the osgi container. In this case, this requirement is generated, one simple solution is to compile a bundle and place an osgi service in the bundle that allows you to set external classloader. For example:
Public class classloaderservice {

Public void setclassloader (classloader );

}
Then, based on the above method, execute the setclassloader method of the osgi service classloaderservice in the external class that starts equinox, and set the external classloader, then, when the osgi container plug-in needs to load classes outside the osgi container, it calls the classloaderservice to load the classes.

Based on the methods mentioned above, osgi containers can be better integrated with other containers, such as activating osgi in Tomcat, however, the dynamic mechanism is not so well handled, unless the external container can also provide the corresponding dynamic mechanism. In the next blog, I will discuss the dynamic mechanism of osgi in detail.

Contact Us

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.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.