Wednesday, March 4, 2009

Error when converting struts jar into bundle with Bnd

I did face errors when converting struts jar into bundles using bnd tool.

The problem was the name of the package:

...i18n.calendar.nls.pt-br;resolution:=opti...

The package pt-br contains a - sign. According to the Java spec, this is not a package name. The OSGi specification does therefore not allow you to export a package that includes a - sign.

Once i removed these packages from the manifest file , it worked fine .

Bnd tool for converting jars into bundles OSGi

This provides a easy way of converting jars into bundles.This does a brute force check and writes every package present in the jar as export and all imports in the java files inot manifest imports.

The command to convert jar into bundle is

java -jar bnd.jar wrap xxx.jar

Its better to check in the Spring Repository for the available bundle before converting it from a a jar to bundle.

http://www.springsource.com/repository/app/

Ref :

http://www.aqute.biz/Code/Bnd

http://blog.springsource.com/2008/02/18/creating-osgi-bundles/

Improving Eclipse performance

Try the below configuration on experimental basis to improve this performance

In the eclipse installation directory parallel to eclipse.exe you will find a file called eclipse.ini

modify it to have the following changes

Change the XXMaxPermSize to 256M
Change the min and max heap size to be 512
Restart eclipse.

--launcher.XXMaxPermSize
256M
-Xms512m
-Xmx512m

Tiimout params for spring remoting

All properties can be set for spring remoting including connection timeout.

The HttpInvokerProxyFactoryBean takes in httpInvokerRequestExecutor as a parameter which in turn takes in httpClient(org.apache.commons.httpclient.HttpClient).

Hence all properties for HttpClient as timeout , connectiontime etc can be set.

Code snippet for injecting httpclient into the connection object(with timeout for 5 seconds)

<bean id="httpParamObject"
class="org.springframework.remoting.httpinvoker.CommonsHttpInvokerRequestExecutor">
<property name="httpClient">
<bean class="org.apache.commons.httpclient.HttpClient">
<property name="timeout" value="5000" />
</bean>
</property>
</bean>

<bean id="testServer"
class="org.springframework.remoting.httpinvoker.HttpInvokerProxyFactoryBean">
<property name="serviceUrl"
value="http://10.1.66.109:8080/server/TestServer" />
<property name="serviceInterface"
value="com.pg.server.IServerImpl" />
<property name="httpInvokerRequestExecutor" ref=" httpParamObject" />

</bean>

Jnotify - monitor file system Events

JNotify is a java library that allow java application to listen to file system events, such as:

* file created.
* file modified.
* file renamed.
* file deleted

JNotify works on both Windows (Windows 2000, XP, Vista) and Linux with INotify support (Kernel 2.6.14 and above).

http://jnotify.sourceforge.net/

Strut 2 performance Tips

Set devmode false

Set template caching true

Define custom interceptor stack. Remove interceptors that are not required.

In classes we can create a templates folder and customize the way js files and templates are loaded.

Ref: http://struts.apache.org/2.0.11.1/docs/performance-tuning.html

Removing tomcat from Spring Dm to reduce memory

By commenting out the servlet subsystem, there should be no Tomcat running in dm Server ß

In profile.config comment as indicated below to disable the tomcat instance.

/* * SpringSource dm Server profile manager default configuration file. */
"profile": { "version" : 1.0, "name" : "web", "subsystems" : [/* "com.springsource.server.servlet", "com.springsource.server.web" */], "optionalSubsystems" : [/* "com.springsource.server.management" */] }}

Mem usage

WITH TOMCAT - 68MB W

WITHOUT TOMCAT - 51 MB ( so 17 MB less)

Ref :http://forum.springframework.org/showthread.php?p=216805

Aspect J load Time Weaving

I am able to inject spring container managed beans into Struts action classes using aspect-j load time weaving (without using struts2-springplugin jar ).
Steps

Add the following lines into the spring xml

<context:spring-configured />

<context:annotation-config />

This is for the identification of the annotations inside classes

<context:load-time-weaver aspectj-weaving="on"/>

This is to enable the weaving
2.include @Configurable annotation above the class name

3.Autowire any spring component bean using autowired annotation @Autowired

4.The following jars need be included (both are bundles with spring Dm server)

com.springsource.org.aspectj.weaver &
com.springsource.org.aspectj.runtime
For this to work the container should be having a class loader which is capable of weaving and Spring DM server is capable of it


By adding the above @Configurable tag any class instantiated (either by reflection or by non spring container) can be associated with the beans created by spring container .The byte code injecting into the class happensthrough aspectj load time weaving.


But I am not sure how costly is this process.

Buddy Classloading Equinox Osgi

Buddy class loading offers an integration strategy that does not require modifying the Java code of existing libraries(like hibernate) , thatuse the Class.forName(String) approach to dynamically discover and load classes.The mechanism works as follows:


A Bundle declares that it needs the help of other bundles to load classes The Bundle identifies the kind of help they need by specifying a buddy policy. The policy defines what kind of bundles will be considered to be buddies. When a bundle class loader fails to find a desired class through the normal OSGi delegation model (i.e. Import-Package, Require-Bundle, and local classpath), its buddy policy is invoked The invoked buddy policy discovers a set of buddies and consults each one in turn until either the class is found or the list is exhausted.

There are different buddy policies like registerd,global etc which can be mentioned in the manifest headers.


This buddy policy is spcific to equinox implementaion and may not be found in all Osgi implementataion.

The use cas eof this is each bundle need not mention an import and still can use the class of the bundle. Its use case is in packages like hibernate which do a class.forname on custom code .


http://wiki.eclipse.org/index.php/Context_Class_Loader_Enhancements

Fragment bundles in OSGi


Fragments are bundles that are attached to a host bundle by the Framework.Attaching is done as part of resolving: the Framework appends the relevantdefinitions of the fragment bundles to the host’s definitions before the hostis resolved. Fragments are therefore treated as part of the host, including any permitted headers.


These fragemnt bundles will not have a seperate class loader. these will belaoded by the same bundle class loader.For a bundle to be a fragment it has to mention fragment host in its manifest file.


This property of fragments can just be used for a logical seperation of classes , examples could be resource bundles which can be packed in to a seperate bundle.


Since these fragment bundles use the same class loader as the host bundlle there is no provision of seperately refreshing the fragment bundle

Ref : http://osgi.mjahn.net/2008/03/13/half-bundle-half-jar-%E2%80%93-the-nature-of-fragment-a-blessing-or-a-curse/

Bundles having same package structure for export :Require bundle Split packages

I was stuck in cases where i had two bundle having the same package structure and they wanted to share these classes.
Osgi just looks into only one of this package and then for any further requests it will look into this folder, if not found gives a class not found exception even though its present in the other bundle.
This case can be solved by using the concept of split packages.
The bundle which needs classes from multiple bundles having the same package structure should define those two bundles as Require-Bundle in its manifest headers in the order in which it should look for.
By doing so the environment ensures that both the bundles will be scanned one after the other to look for the requested classes.
Still i would prefer to refactor the jars than use this feature of require bundle.

Bundle Class Path - best way to start Osgi-Bundle Class PathIntra

bundle class path dependencies are declared in the Bundle-Classpathmanifest header. This declaration allows a bundle to declare its embedded class path using one or more JAR files or directories that are contained in the bundle’s JAR file.
This was the idle use case for me , where i converted only one jar into a bundle and gave all other jars in its bundle classpath.This gave me a flexibility where i needed to merge all the jars into one.
This will help as a starting point. All the class under the bundle classpath will be laoded by the single bundle classlaoder.
I tried the same with fragment bundles but with no luck , as it threw class not found exceptions in the cases which included RMi connections.

Order of search for a class in Osgi -> Resolving Process

1 If the class or resource is in a java.* package, the request is delegated tothe parent class loader; otherwise, the search continues with the nextstep. If the request is delegated to the parent class loader and the class orresource is not found, then the search terminates and the request fails.


2 If the class or resource is from a package included in the boot delegationlist (org.osgi.framework.bootdelegation), then the request is delegatedto the parent class loader. If the class or resource is found there, thesearch ends.


3 If the class or resource is in a package that is imported using Import-Package or was imported dynamically in a previous load, then therequest is delegated to the exporting bundle’s class loader; otherwise thesearch continues with the next step. If the request is delegated to anexporting class loader and the class or resource is not found, then thesearch terminates and the request fails.


4 If the class or resource is in a package that is imported from one or moreother bundles using Require-Bundle, the request is delegated to the classloaders of the other bundles, in the order in which they are specified inthis bundle’s manifest. This entails a depth-first strategy; all requiredbundles are searched before the bundle classpath is used. If the class orresource is not found, then the search continues with the next step.


5 The bundle’s own internal bundle class path is searched. If the class orresource is not found, then the search continues with the next step.


6 Each attached fragment’s internal bundle class path is searched. The fragmentsare searched in ascending bundle ID order. If the class or resourceis not found, then the search continues with the next step.


7 If the class or resource is in a package that is exported by the bundle orthe package is imported by the bundle (using Import-Package or Require-Bundle), then the search ends and the class or resource is not found.


8 Otherwise, if the class or resource is in a package that is imported usingDynamicImport-Package, then a dynamic import of the package is nowattempted. An exporter must conform to any implied package constraints.If an appropriate exporter is found, a wire is established so thatfuture loads of the package are handled in Step 3. If a dynamic wire is notestablished, then the request fails.


9 If the dynamic import of the package is established, the request is delegatedto the exporting bundle’s class loader. If the request is delegated toan exporting class loader and the class or resource is not found, then thesearch terminates and the request fails.

System packages and Extender packages in OSGi

The OSGi spec allows the Framework (through its system bundle) to export the relevant packages from its parent classloader as system packages using the org.osgi.framework.system.packages property.As repacking the hosting JDK as a bundle isn't a viable option, one can use this setting to have the system bundle (or the bundle with id 0) export these packages itself.


Extension Bundles :Another possible option is to enhance the system bundle through extension bundles. These act as fragments;they are not bundles of their own but rather are attached to a host. Once attached, the fragment content (including any permitted headers) is treated as part of the host. Extension bundles are a special kind of fragments that get attached only to the Systembundle in order to deliver optional parts of the Framework (such as the Start Level service).


The System package entry is added using org.osgi.framework.system.packages = \ i
n java6-server.profile in the lib directory of the dm server


In both the above cases the classes are loaded by the bootclassloader and not a seperate bundle classloader.Hence these are candidates when we are considering putting classes at the boot class path.

ref:http://blog.springsource.com/2009/01/19/exposing-the-boot-classpath-in-osgi/.

Class.forname and classloader.loadclass - whats bettr in OSGi

ClassLoader.loadClass or Class.forName seem to be synonyms for the same basic operation:
but class.forname does additional constraint checks which can cause some problems in the context of OSGi.So it does seem reasonable to have Class.forName behavior altered to avoid loader constraint checks.
However, if Class.forName is used to call the initiating class loader, the behavior with respect to cachinga nd the returned class is quite different. In this case, when the class is first defined, it is cached by the defining class loader as expected. But it is also cached by the initiating class loader which is not expected.
As a result, all calls to Class.forName to a initiating class loader always return the same class object (thefirst one loaded), even if the implementation of the initiating class loader does not define classes or directlyconsult its own cache.
My case where class.forname didnt wrk and classloader.loadclass worked
Scenario:
Bundle A->class AA, extends Server,calls init

class ToBeLoaded ,exports ToBeLoaded
Bundle B->class Server, method init()->tries to load class ToBeLoaded

Ref : http://blog.bjhargrave.com/2007/07/why-do-classforname-and.html
http://blog.bjhargrave.com/2007/09/classforname-caches-defined-class-in.html

http://www.jroller.com/navanee/entry/difference_between_class_forname_and

Using Custom Class Loaders In Spring Dm -OSGi

One has to be careful while using custom class loaders in any of the bundles.This is beacuse in the context of osgi each bundle will have a classloader whose parent will be the bootclassloader.
And the hierarchy of the classes searched will be delegated from child to the parent classloader. Hence when a class is not found in a bundle, the responsibility will be delegated to the parent classloader.
When we define a custom classloader as follows
CustomClassLoader = new CustomClassaloader() - > its parent is set to the boot classloader. Hence though its inside the bundle it canot see any classes inside the bundle .
The easy way to get away from this is to set the custom class laoders parent as the bundle classloader.Now any request to the classes in the custom class loader will be delegated to its parent that is the bundle classloader and the clases will be found.

Classloader hierachy in Spring Dm - OSGi


When a bundle is deployed into the spring dm the follwing will be the classloader structure
In the case of bundle

Current classlaoder ->LoaderServerBundleClassLoader: (Bundle calssloader)

Parent1 ->sun.misc.Launcher$AppClassLoader@1754ad2

Parent2 ->sun.misc.Launcher$ExtClassLoader@1833955
In the case os a class put in the boot delegation path

Current Class Loader->sun.misc.Launcher$AppClassLoader@1754ad2

Parent1 ->sun.misc.Launcher$ExtClassLoader@1833955

Parent2 ->null

Ref :http://blog.bjhargrave.com/2007/07/why-do-classforname-and.html

OSGi - Putting classes into Boot delegation path

To put any classes into the the boot delegation path in Osgi the follwoing needs to be done
add the entry into org.osgi.framework.bootdelegation
in the follwing file --> springsource-dm-server-ee-1.0.1.RELEASE\lib\java6-server.profile
Once classes are added into the this boot path there is no need to import this in any of the bundle manifests.
But the disadvantage here is that these classe are loaded by the Boot Class loader , and hence we loose the independent runtime deployments of these classes.
But this trick can be used while integrating with teraacotta or other cases , where we can give away independent deploymenta dvantage , but get flexibilty of loading these classes using boot class laoder and also have these classes directly without any imports.

The other way of getting classes under boot class path is to make it system package or extender bundle of a system package.

Osgi - Package Imports to Shared Services Benefits

Whenever a bundle gets updated in a OSgi environments the direct affect is that all bundles which have any import will also get bounced . This information is not displayed in the dm server console.
I have observed this change only by putting sysouts in the bundle activator. I feel this should not be hidden in the console.
This will also happen in the service model if the interfaces are bundled along with the implementation.
Bundle a -> Implementation & interface and provides Osgi service
Bundle c -> osgi service importer,has import for intercface packages from a
Now if we bounce the bundle a to change the implementaion bundle c also gets refreshed though we dont change the interface.
The only way to avoid this is to have a seperate bundle b with interface
Bundle b - > has interface
and now bundle c imports from bundle b , also bundle a imports from bundle b . Thus any changes in bundle a, thats the implementaion will not have any refresh of other bundles.

Modifying the web pages inside OSGi web bundle

The imapct of packaging into a web module in OSgi was that we lost the ability to modify JSp pages on the fly. This was a drawback since our teams used to modify the JSps in production environment very often.
Spring Dm has promised to avoid this change by providing a flexibilty to allow breaking of web bundles into multiple parts and allow for thier independent deployments in the future releases.
Untill then the hack could be to commit the jsp pages into the work directory and it gets reflected.
Location for change
.\SpringServer\work\com.springsource.server.deployer\Module\Bundle-A.jar-0\Bundle-A.jar\MODULE-INF\jsp\data.jsp

Spring Dm(OSGi) integration with terracota

I have tried integrating terracotta with spring DM and it works fine. My use case included a instance a stand alone java,jetty web server,apache tomcat and Spring Dm connected to the same instance of terracotta sharing a custom class as the root.
The changes i had to make were
Added the Terracotta lib and shared classes under boot delegation path of Spring DM –
1. In springsource-dm-server-ee-1.0.1.RELEASE\lib\java6-server.profile org.osgi.framework.bootdelegation = \ com.tc.*,\--> àddedd this is to avoid errors from Spring DM which tries to load these classes from Bundle class loader share.* --> Classes which are shared
2 .Copied shared jar under springsource-dm-server-ee-1.0.1.RELEASE\lib\
The above changes are doen to ensure that teh shared classes are loaded by the boot classloader which will enable terracotta toidentify this class and share with other processes()stadalobe,jetty.tomcat).In teh above case since the shared jar is added intothe bootdelegation , any chage in the teracotta shared classes will need restart of the spring dm server.

The other staratergy to achive the same is by changing the classloader names in all the other processes which are connected to terracotta, but i found this more complicated and cumbersome.

 
Free Domain Names @ .co.nr!