[jboss-user] [Beginners Corner] - Re: Howto install custom classloader
Deady
do-not-reply at jboss.com
Fri Nov 7 10:01:05 EST 2008
For simplicity let's load class from file.
here's a trick:
1. create classloader
| package test.jboss;
|
| import org.jboss.logging.Logger;
| import org.jboss.mx.loading.RepositoryClassLoader;
|
| import javax.management.MalformedObjectNameException;
| import javax.management.ObjectName;
| import java.net.URL;
| import java.io.FileInputStream;
| import java.io.IOException;
|
| /**
| * User: Deady
| * Date: 06.11.2008
| * Time: 16:58:53
| */
|
| public class DBClassLoader extends RepositoryClassLoader {
|
|
| protected Logger log;
| private String name;
|
|
| /**
| * Create a new LoaderRepositoryClassLoader
| *
| * @param parent the parent classloader
| */
| public DBClassLoader(String name, URL[] url, ClassLoader parent) {
| super(url, parent);
| this.name = name;
| this.log = org.jboss.logging.Logger.getLogger(getClass().getName());
| }
|
| public ObjectName getObjectName() throws MalformedObjectNameException {
| return new ObjectName("dbclassloader");
| }
|
| public Class loadClass(String name, boolean resolve) throws ClassNotFoundException {
| log.info("loading class: "+name);
| return super.loadClass(name, resolve);
| }
|
| public URL getResourceLocally(String name) {
| log.info("getting resource locally: "+name);
| return getURL();
| }
|
| public Class loadClassLocally(String name, boolean resolve) throws ClassNotFoundException {
| log.info("loading class locally: "+name);
| String file = "/home/Deady/testbean/classes/"+name.replace(".","/")+".class";
| byte[] b = null;
| int readen = 0;
| try {
| FileInputStream in = new FileInputStream(file);
| b = new byte[in.available()];
| readen = in.read(b);
| in.close();
| } catch (IOException e) {
| e.printStackTrace();
| }
| return defineClass(name, b, 0, readen);
| }
|
| public Package[] getPackages() {
| log.info("return packages: "+getPackage(name));
| return new Package[]{getPackage(name)};
| }
| }
|
2. create deployer MBean:
| package test.jboss;
|
| import org.jboss.deployment.DeploymentException;
| import org.jboss.deployment.DeploymentInfo;
| import org.jboss.deployment.SubDeployerSupport;
| import org.jboss.logging.Logger;
|
| import java.net.URL;
|
| /**
| * User: Deady
| * Date: 06.11.2008
| * Time: 13:42:03
| */
| public class DBDeployerMBean extends SubDeployerSupport {
|
| protected Logger log;
|
| public DBDeployerMBean() {
| this.log = org.jboss.logging.Logger.getLogger(getClass().getName());
| }
|
| public boolean accepts(DeploymentInfo di) {
| String urlStr = di.url.toString();
| String extension = getExtension();
| boolean res = urlStr.endsWith(extension);
| if (res) {
| log.info("accepted: "+di);
| }
| return res;
| }
|
|
| public void init(DeploymentInfo di) throws DeploymentException {
| log.info("initializing: "+di);
| try {
| di.createClassLoaders();
| di.ucl.getLoaderRepository().addClassLoader(new DBClassLoader("foo", new URL[]{di.localUrl}, di.ucl));
| } catch (Exception e) {
| e.printStackTrace();
| }
| super.init(di);
| }
|
| protected void deployUrl(DeploymentInfo di, URL url, String name) throws DeploymentException {
| log.info("di: "+di+", url:"+url+", name: "+name);
| super.deployUrl(di, url, name);
| }
|
| public String getExtension() {
| return ".dbr";
| }
|
| }
|
3. create sar descriptor:
| <?xml version="1.0" encoding="UTF-8"?>
| <!--
| The JBoss service configuration file for the EJB deployer service.
|
| $Id: ejb-deployer.xml 62317 2007-04-13 10:39:22Z dimitris at jboss.org $
| -->
| <server>
|
|
| <!-- ==================================================================== -->
| <!-- DB Deployer -->
| <!-- ==================================================================== -->
|
| <!-- EJB deployer, remove to disable EJB behavior-->
| <mbean code="test.jboss.DBDeployerMBean" name="jboss.ejb:service=DBDeployer" xmbean-dd="">
|
| <!-- Inline XMBean Descriptor BEGIN -->
| <xmbean>
| <description>The DBDeployer responsible for dbr jar deployment</description>
| <class>test.jboss.DBDeployerMBean</class>
|
| <!-- ServiceMBean operations -->
| <operation>
| <description>Standard MBean lifecycle method</description>
| <name>create</name>
| </operation>
|
| <operation>
| <description>The start lifecycle operation</description>
| <name>start</name>
| </operation>
|
| <operation>
| <description>The stop lifecycle operation</description>
| <name>stop</name>
| </operation>
|
| <operation>
| <description>The destroy lifecycle operation</description>
| <name>destroy</name>
| </operation>
|
| <operation>
| <description>The detyped lifecycle operation (for internal use only)</description>
| <name>jbossInternalLifecycle</name>
| <parameter>
| <description>The lifecycle operation</description>
| <name>method</name>
| <type>java.lang.String</type>
| </parameter>
| <return-type>void</return-type>
| </operation>
|
|
| <!-- SubDeployerMBean operations -->
| <operation>
| <description>Accept a module for deployment</description>
| <name>accepts</name>
| <parameter>
| <name>info</name>
| <type>org.jboss.deployment.DeploymentInfo</type>
| </parameter>
| <return-type>boolean</return-type>
| </operation>
|
| <operation>
| <description>Initialize deployment step</description>
| <name>init</name>
| <parameter>
| <name>info</name>
| <type>org.jboss.deployment.DeploymentInfo</type>
| </parameter>
| </operation>
|
| <operation>
| <description>Create deployment step</description>
| <name>create</name>
| <parameter>
| <name>info</name>
| <type>org.jboss.deployment.DeploymentInfo</type>
| </parameter>
| </operation>
|
| <operation>
| <description>Start deployment step</description>
| <name>start</name>
| <parameter>
| <name>info</name>
| <type>org.jboss.deployment.DeploymentInfo</type>
| </parameter>
| </operation>
|
|
| <operation>
| <description>Stop deployment step</description>
| <name>stop</name>
| <parameter>
| <name>info</name>
| <type>org.jboss.deployment.DeploymentInfo</type>
| </parameter>
| </operation>
|
| <operation>
| <description>Destroy deployment step</description>
| <name>destroy</name>
| <parameter>
| <name>info</name>
| <type>org.jboss.deployment.DeploymentInfo</type>
| </parameter>
| </operation>
|
|
| </xmbean>
|
|
| </mbean>
|
| </server>
|
4. pack sar and copy it to server:
/jboss/server/deploy/dbdeployer.sar
+METAINF
++jboss-service.xml
+dbdeployer.jar
5. create and deploy test.ddr - this is simple jar file:
test.dbr
+META-INF
++INDEX.LIST
content of INDEX.LIST:
| ddd
|
| db.jar
| foo
|
6. create test bean:
| package test;
|
| import javax.ejb.Remote;
|
| /**
| * User: Deady
| * Date: 06.11.2008
| * Time: 17:08:24
| */
| @Remote
| public interface TestClassLoader {
|
| public Object loadClass(String className);
|
| }
|
| package test;
|
| import org.jboss.annotation.ejb.RemoteBinding;
|
| import javax.ejb.Stateless;
|
| /**
| * User: Deady
| * Date: 06.11.2008
| * Time: 17:09:06
| */
| @Stateless(name="DBClassLoader")
| @RemoteBinding(jndiBinding="test/DBClassLoader/remote")
| public class TestClassLoaderImpl implements TestClassLoader{
|
| public Object loadClass(String className) {
| try {
| Class cl = Thread.currentThread().getContextClassLoader().loadClass(className);
| System.out.println("loaded = " + cl);
| Object o = cl.newInstance();
| return o;
| } catch (Exception e) {
| e.printStackTrace();
| }
| return null;
| }
| }
|
|
7. create test class:
| package foo;
|
| import java.io.Serializable;
|
| /**
| * User: Deady
| * Date: 07.11.2008
| * Time: 17:19:00
| */
| public class Test implements Serializable {
|
| public String hello() {
| return "hello world3";
| }
|
| }
|
|
compile it and copy to path, from which DBClassLoader will read it ("/home/Deady/testbean/classes/" in my case)
8. test it works:
| package test;
|
| import foo.Test;
|
| import javax.naming.InitialContext;
| import javax.naming.Context;
| import java.util.Properties;
|
| /**
| * User: Deady
| * Date: 06.11.2008
| * Time: 17:16:26
| */
| public class Client {
|
| public static void main(String[] args) throws Exception {
| Properties p = new Properties();
|
|
| p.put("java.naming.factory.initial", "org.jnp.interfaces.NamingContextFactory");
| p.put("java.naming.factory.url.pkgs", "org.jboss.naming:org.jnp.interfaces");
| p.put(Context.PROVIDER_URL, "jnp://192.168.0.87:1099");
| InitialContext ctx = new InitialContext(p);
| TestClassLoader l = (TestClassLoader) ctx.lookup("test/DBClassLoader/remote");
| Object c = l.loadClass("foo.Test");
| if (c==null) {
| System.out.println("null");
| }
| else {
| if (c instanceof Test) {
| System.out.println(((Test)c).hello());
| }
| else {
| System.out.println(c.getClass());
| }
| }
|
|
| }
|
| }
|
|
|
View the original post : http://www.jboss.com/index.html?module=bb&op=viewtopic&p=4187739#4187739
Reply to the post : http://www.jboss.com/index.html?module=bb&op=posting&mode=reply&p=4187739
More information about the jboss-user
mailing list