-
1. Re: JBoss 5 custom deployers and classloaders
alesj Mar 18, 2010 2:14 PM (in response to thebaz)1 of 1 people found this helpfulHow can I tell the custom deployer to make the class, contained into the jar, be visible to EAR application? Am I following the right path? Is there a code sample that does a similar work? Is this problem solvable?
If EAR is not scoped you should already see this jar's classes.
If it is scoped, you need to "attach" the jar to this EAR's cl domain.
-
2. Re: JBoss 5 custom deployers and classloaders
thebaz Mar 19, 2010 9:35 AM (in response to alesj)Thanks Ales,
If EAR is not scoped you should already see this jar's classes.
Correct, I see class of an external jar deployed
If it is scoped, you need to "attach" the jar to this EAR's cl domain.
It is not clear to me where/when attach the jar to EAR's classloader domain, it must be done by the custom deployer? Can you privide a snippet of code or a sample to do this?
Thank-you in advance,
Marco.
-
3. Re: JBoss 5 custom deployers and classloaders
alesj Mar 19, 2010 1:23 PM (in response to thebaz)If it is scoped, you need to "attach" the jar to this EAR's cl domain.
It is not clear to me where/when attach the jar to EAR's classloader domain, it must be done by the custom deployer? Can you privide a snippet of code or a sample to do this?
While you create "artificial" jar, you simply need to add proper ClassLoadingMetaData --> jboss-classloading.xml.
* http://java.dzone.com/articles/jboss-microcontainer-classloading
-
4. Re: JBoss 5 custom deployers and classloaders
thebaz Mar 23, 2010 4:13 PM (in response to alesj)Thanks Ales,
that was perfect. I got the point.
Now I'm focusing on a sligthly different think:
I have my deployers. First one parses XML file and get meta-data:
public class MibArchiveDeployer extends JAXBDeployer<MibDeployment> { private static Logger log = Logger.getLogger(MibArchiveDeployer.class); /** * Create a new MibArchiveDeployer. */ public MibArchiveDeployer() { super(MibDeployment.class); setSuffix("-mib.xml"); // Enable the super class ManagedObjectCreator implementation setBuildManagedObject(true); setAllowMultipleFiles(true); } /** * Parse a deployment * * @param unit the deployment unit * @param file the metadata file * @param root - possibly null pre-existing root * @return the metadata * @throws Exception for any error */ @Override protected MibDeployment parse(VFSDeploymentUnit unit, VirtualFile file, MibDeployment root) throws Exception { MibDeployment mibDeployment = super.parse(unit, file, root); log.info(format("MibDeployment found: %s", mibDeployment.toString())); return mibDeployment; } }
Second one which actually deploys the jar archive:
public class SnmpBeanDeployer extends AbstractSimpleRealDeployer<MibDeployment> { private static Logger log = Logger.getLogger(SnmpBeanDeployer.class); /** The service controller */ private final ServiceController serviceController; /** * Create a new SnmpBeanDeployer. * @param serviceController service controller */ public SnmpBeanDeployer(ServiceController serviceController) { super(MibDeployment.class); if (serviceController == null) throw new IllegalArgumentException("Null service controller."); this.serviceController = serviceController; } /** * Deploy a deployment * * @param unit the unit * @param deployment the attachment * @throws org.jboss.deployers.spi.DeploymentException * for any error */ @Override public void deploy(DeploymentUnit unit, MibDeployment deployment) throws DeploymentException { try { AbstractVFSDeploymentUnit vfsDeploymentUnit = (AbstractVFSDeploymentUnit) unit; VirtualFile jarFile = vfsDeploymentUnit.getRoot(); log.info(format("VirtualFile: %s", jarFile)); //VirtualFile integration = VFS.getRoot(deployment.getVirtualFileURL()); MBeanServer mBeanServer = serviceController.getMBeanServer(); log.info(format("MBeanServer: %s", mBeanServer)); } catch (Throwable t) { throw DeploymentException.rethrowAsDeploymentException("Error deploying unit.", t); } } }
What I want to do is let the second deployer deploy my jar only after an EJB3 present in my EAR is deployed in order to save some info into database.
Am I right I if re-write parse method of first deployer adding following code?
protected MibDeployment parse(VFSDeploymentUnit unit, VirtualFile file, MibDeployment root) throws Exception { MibDeployment mibDeployment = super.parse(unit, file, root); log.info(format("MibDeployment found: %s", mibDeployment.toString())); ObjectName objectName = new ObjectName(ejbName); unit.addIDependOn(new LifecycleDependencyItem(ejbName, objectName.getCanonicalName(), ControllerState.START)); return mibDeployment; }
where ejbName is the JDNI name of my EAR's EJB3
-
5. Re: JBoss 5 custom deployers and classloaders
alesj Mar 24, 2010 12:59 AM (in response to thebaz)Am I right I if re-write parse method of first deployer adding following code?
protected MibDeployment parse(VFSDeploymentUnit unit, VirtualFile file, MibDeployment root) throws Exception { MibDeployment mibDeployment = super.parse(unit, file, root); log.info(format("MibDeployment found: %s", mibDeployment.toString())); ObjectName objectName = new ObjectName(ejbName); unit.addIDependOn(new LifecycleDependencyItem(ejbName, objectName.getCanonicalName(), ControllerState.START)); return mibDeployment; }
where ejbName is the JDNI name of my EAR's EJB3
Almost. :-)
Currently you're using the ejbName twice, for item owner and its dependency, which is wrong.
Check how this is done in jboss-dependency.xml handing code in Deployers -- org.jboss.deployers.vfs.plugins.dependency.
* Object contextName = unit.getControllerContextName();
Perhaps you can even reuse some of the DeploymentDependencies logic.
ps: no need for
LifecycleDependencyItem, plain
AbstractDependencyItem will do -
6. Re: JBoss 5 custom deployers and classloaders
thebaz Mar 24, 2010 8:21 AM (in response to alesj)Hi Ales,
I've added in the META-INF folder of the to-be-deployed jar this jboss-depencency.xml file:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?> <dependency xmlns="urn:jboss:dependency:1.0"> <item whenRequired="Real" dependentState="Create">my.domain:service=MyServiceMBean</item> </dependency>
And my first deployer parse method source code looks like this:
MibDeployment mibDeployment = super.parse(unit, file, root); log.info(format("MibDeployment found: %s", mibDeployment.toString())); ObjectName objectName = new ObjectName(mibMBeanName); Object contextName = unit.getControllerContextName(); unit.addIDependOn(new AbstractDependencyItem(contextName, objectName.getCanonicalName(), ControllerState.DESCRIBED, ControllerState.INSTALLED)); return mibDeployment;
Where mibMBeanName is: my.domain:service=MyServiceMBean
But it did not work. Jar is deployed before my MBean is installed.
Where's the bug?
Thank-you in advance,
Marco.
-
7. Re: JBoss 5 custom deployers and classloaders
adrian.brock Mar 24, 2010 12:14 PM (in response to thebaz)1 of 1 people found this helpfulYou are trying to use ControllerState.DESCRIBED for a deployment which is wrong.
That is for determining dependencies for pojos/mbeans etc.
You want to use:
ControllerState.newState(DeploymentStages.DESCRIBE.getName());
which is used for describing classloading dependencies for deployments.
NOTE, there is no D on the end, sorry for the confusion in the names. ;-)
In fact, ControllerState.DESCRIBED will come after DeploymentStages.REAL
which explains why your dependency is not working.
It will have already done all the Deployment processing by then.
-
8. Re: JBoss 5 custom deployers and classloaders
adrian.brock Mar 24, 2010 12:16 PM (in response to adrian.brock)Adrian Brock wrote:
You want to use:ControllerState.newState(DeploymentStages.DESCRIBE.getName());
which is used for describing classloading dependencies for deployments.
NOTE, there is no D on the end, sorry for the confusion in the names. ;-)
I guess a better name would have been PRE_CLASSLOADER, but its a bit late to change it now. :-(
-
9. Re: JBoss 5 custom deployers and classloaders
adrian.brock Mar 24, 2010 12:34 PM (in response to thebaz)Marco Bazzoni wrote:
And my first deployer parse method source code looks like this:MibDeployment mibDeployment = super.parse(unit, file, root); log.info(format("MibDeployment found: %s", mibDeployment.toString())); ObjectName objectName = new ObjectName(mibMBeanName); Object contextName = unit.getControllerContextName(); unit.addIDependOn(new AbstractDependencyItem(contextName, objectName.getCanonicalName(), ControllerState.DESCRIBED, ControllerState.INSTALLED)); return mibDeployment;
You also don't want to do that in the parse() method. It won't get invoked if somebody passes in the MibDeployment as
an attachment (e.g. the management console overriding the metadata) rather than parsing from xml.
You should do the extra processing in the init() method which always gets invoked regardless of where the metadata came from.
-
10. Re: JBoss 5 custom deployers and classloaders
thebaz Mar 24, 2010 12:44 PM (in response to adrian.brock)Thank-you Adrian,
but method newState in class ControllerState is not present:
I use this class org.jboss.dependency.spi.ControllerState in org.jboss.microcontainer:jboss-dependency:2.0.6.GA
Wrong dependency?
Marco
-
11. Re: JBoss 5 custom deployers and classloaders
adrian.brock Mar 24, 2010 12:56 PM (in response to thebaz)1 of 1 people found this helpfulIf you are using an older version of jboss-dependency then use
new ControllerState(DeploymentStages.DESCRIBE.getName());
instead.
The newState() method was added later to avoid too many instances getting constructed.
-
12. Re: JBoss 5 custom deployers and classloaders
thebaz Mar 24, 2010 1:07 PM (in response to adrian.brock)Adrian Brock wrote:
If you are using an older version of jboss-dependency then use
new ControllerState(DeploymentStages.DESCRIBE.getName());
instead.
The newState() method was added later to avoid too many instances getting constructed.
Ok, Adrian it worked good. Thank-you to you and Ales for helpfully hints.
Bests,
Marco.