Showing posts with label Others. Show all posts
Showing posts with label Others. Show all posts

Saturday, August 8, 2009

Thread Context ClassLoader / Buddy ClassLoading in OSGi.

Bundles like Struts,hibernate,Spring need to instantiate classes in custom application bundle.In normal cases this can be directly done because there is a single class space(single class loader).

Consider a case where there are more than one class loaders .Lets take a simple case in which the struts/spring jar is kept under tomcat common lib and your application classes are under the web-inf lib. These two are jars now are loaded by two different classloaders.
Tomcat common lib class loader being the parent of tomcat web-inf/lib class loader.Also classloader of struts jar cannot see application classes in web-inf lib.

Now how can struts/spring see application classes ?

To solve such problems java Java came up with a solution called Thread Context Class Loader(TCCL). Thread context class loader was introduced in Java 2 to enable frameworks running in application servers to access the "right" application class loader for loading application classes.

This is accessed using Thread.getCurentThread.getContextClassloader().Its as simple as, It is the classloader associated with each thread.There are setter methods which can be called to set this TCCL.

By the definition in tomcat the TCCL is set to the context class loader from where the thread begins.So TCCL has the classloader visibity of web-inf lib,solving our problem.

Now since the thread started from that application ,these third party jars can use TCCL to instantiate application classes. The control starts from our application bundle and then flow moves to some third party bundle like struts or hibernate,which internally in their
source code use TCCL to instantiate our classes.

TCCL becomes slightly more complicated in the case of OSGI.

I have a small POC for the Reflection based Class loading using TCCL.

Source Code : http://www.4shared.com/file/123739699/3b6dd30e/TCCLosgi.html

Bundle 3(Core bundle) – has reflection code to instantiate application classes. Uses TCCL to instantiate classes.

Bundle 2 (Service) –Using the core bundle to instantiate its classes (imports bundle 3 classes directly)

Bundle 1 (Application) – uses the OSGi service provided by bundle 2.


Control Flow:

Bundle 1 makes a OSGi service call to bundle 2.

Bundle 2 now uses core to instantiate its(bundle 2) classes.

Result: ClassNotFoundException

Reason:

Bundle 2 is able to instantiate classes only in Bundle 3 and not in Bundle.

This is because TCCL has visibility only to class loader from where the thread started.

Solution:

1. PAR(Spring DM solution)

Spring Dm comes with a concept of PAR,which is grouping of bundles.All bundles inside the PAR will contribute together to form a synthetic context.And hence bundles inside it have visibility to all others exisiting inside it.

http://blog.springsource.com/2008/05/02/running-spring-applications-on-osgi-with-the-springsource-application-platform/

2.Buddy Class Loading (this is equinox specific solution and not part of OSGi spec)

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


Now bundle 3, that is the core bundle can be a buddy to bundle 2 (service bundle).

Syntax

In bundle 3 manifest we need to mention Buddy-Policy :registered

In bundle 2 manifest we mention Eclipse-RegisterBuddy : bundle symbolic name


Now at run time we can add new slots(Bundle 4) which registers itself as a buddy to bundle 2(core) ,without affecting any other bundles.

3. We can set the TCCL in bundle 2 to bundle class loader when the deligation goes through it.I guess TCCL may not be the right approach(not good to tamper the class loader prior to making calls across bundles).

We can choose a solution based on the requirement.






Saturday, July 25, 2009

Apache HttpClient

Although the java.net package provides basic functionality for accessing resources via HTTP, it doesn't provide the
full flexibility or functionality needed by many applications. The Jakarta Commons HttpClient component seeks to fill
this void by providing an efficient, up-to-date, and feature-rich package implementing the client side of the most
recent HTTP standards and recommendations

Feature List

http://hc.apache.org/httpclient-3.x/features.html

CGLIB-For Dynamic Proxies

The Spring Framework implements method injection by dynamically generating a subclass overriding the method, using bytecode generation via the CGLIB library.

Please be aware that in order for this dynamic subclassing to work, you will need to have the CGLIB jar(s) on your classpath. Additionally, the class that the Spring container is going to subclass cannot be final, and the method that is being overridden cannot be final either.

By default, when the Spring container is creating a proxy for a bean that is marked up with the <aop:scoped-proxy/> element, a CGLIB-based class proxy will be created. This means that you need to have the CGLIB library on the classpath of your application.

Note: CGLIB proxies will only intercept public method calls! Do not call non-public methods on such a proxy; they will not be delegated to the scoped target object.

You can choose to have the Spring container create 'standard' JDK interface-based proxies for such scoped beans by specifying 'false' for the value of the 'proxy-target-class' attribute of the <aop:scoped-proxy/> element. Using JDK interface-based proxies does mean that you don't need any additional libraries on your application's classpath to effect such proxying, but it does mean that the class of the scoped bean must implement at least one interface, and all of the collaborators into which the scoped bean is injected must be referencing the bean via one of its interfaces.

Spring AOP can also use CGLIB proxies. This is necessary to proxy classes, rather than interfaces. CGLIB is used by default if a business object does not implement an interface. As it is good practice to program to interfaces rather than classes, business classes normally will implement one or more business interfaces. It is possible to force the use of CGLIB, in those (hopefully rare) cases where you need to advise a method that is not declared on an interface, or where you need to pass a proxied object to a method as a concrete type.

Saturday, May 16, 2009

Getting jar name & location from loaded class

The following method with the classname passed as parameter will return the location of the jar from which the class is loaded.

import java.net.URL;
import java.security.CodeSource;
import java.security.ProtectionDomain;

public static String getJarLocation(String className) {
try {
Class cls = Class.forName(className);
ProtectionDomain pDomain = cls.getProtectionDomain();
CodeSource cSource = pDomain.getCodeSource();
URL loc = cSource.getLocation();
return loc.toString();
} catch (Exception e) {
e.printStackTrace();
}

return null;

}

Alternatively we can also add the following to the startup JVM paramteres , which will print all the classes loaded along with the jar names and its path.

-verbose:class

Simple java Regular Expression matching

This simple regular expression matching code just checks for all hyper links in the input string and converts it into proper clickable links in html.

import java.util.regex.*;

public static void main(String args[]) {
System.out.println("test");

String test="sdsfssuwww.yah2oo.com/sds3d jisds sdsds www.google.com/sdsd.htm sds";
Pattern pattern = Pattern.compile("(http://)?www.[a-zA-Z0-9./]*");
Matcher matcher = pattern.matcher(test);

boolean found = false;

while (matcher.find()) {

String a = test.substring(0,matcher.start()-1);
String b =test.substring(matcher.end());
String c=a+"<a href=\""+matcher.group()+"\">"+matcher.group()+"</a> "+b;

System.out.println("a"+a);
System.out.println("b"+b);
System.out.println("c"+c);

found = true;

}
if (!found) {
System.out.println("No match found.");
}

}

 
Free Domain Names @ .co.nr!