Hello all,
I hope I have chosen right forum ;)
I'm using my own dedicated deployer which is responsible for deploying some kind or
archives that are similar to plain EARs. This deployer is derived from SubDeployerSupport
so I have got support for nested deployments out of the box. Deployed archives are not the
EARs so nested EJB3 modules are not deployed as a part of EAR archive. There is a problem
with the InvocationHandlerEJB3 which treats all EJB3 components from modules which have
their parent module set (In DeploymentInfo), as a part of EAR archive and tries to add
"ear" key to their ObjectNames while this key shouldn't be set because these
modules are not deployed as a part of EAR but as a part of other archive (They are
registered the same way as standalone EJB3 modules are.). ObjectName prepared this way is
obviously not known so "Cannot find service endpoint target..." exception is
thrown.
I would like to point here that I use JBoss 4.2.2.GA and jbossws-native 3.0.1 (but
jbossws-native has nothing to do with this problem.)
It is shown in the code below:
| // org.jboss.wsf.container.jboss42.InvocationHandlerEJB3
|
| public void init(Endpoint ep)
| {
| String ejbName = ep.getShortName();
| ArchiveDeployment dep = (ArchiveDeployment)ep.getService().getDeployment();
| String nameStr = "jboss.j2ee:name=" + ejbName +
",service=EJB3,jar=" + dep.getSimpleName();
| if (dep.getParent() != null) <---- Mentioned condition (It is not
DeploymentInfo but this object is based on it)
| {
| nameStr += ",ear=" + dep.getParent().getSimpleName();
| }
|
| objectName = ObjectNameFactory.create(nameStr.toString());
|
| Dispatcher dispatcher = Dispatcher.singleton;
| if (dispatcher.getRegistered(objectName.getCanonicalName()) == null)
| throw new WebServiceException("Cannot find service endpoint target:
" + objectName);
| }
|
In my opinion this condition is not enough because not every parent of EJB3 module has to
be an EAR archive. See "org.jboss.ejb3.Ejb3Module" constructor and method
"getDeploymentQualifiedName" of "org.jboss.ejb3.EJBContainer" to
confirm it. This method returns exactly what is needed in earlier mentioned
"init" method of
"org.jboss.wsf.container.jboss42.InvocationHandlerEJB3".
| // org.jboss.ejb3.EJBContainer
|
| public String getDeploymentQualifiedName()
| {
| DeploymentScope ear = deployment.getEar(); <--- DeploymentScope is a
determinant of EAR.
| DeploymentUnit unit = deployment.getDeploymentUnit();
| StringBuilder sb = new StringBuilder();
| if (ear != null)
| {
| sb.append("ear=");
| sb.append(ear.getShortName());
| sb.append(",");
| }
| sb.append("jar=");
| sb.append(unit.getShortName());
| sb.append(",name=");
| sb.append(getEjbName());
| return sb.toString();
| }
|
EJB3 module is treated as a part of EAR only if Ejb3Deployment (deployment field in this
case) returns an instance of DeploymentScope which is prepared by Ejb3Module for parent
EAR archive. This object is available ONLY if parent archive name ends with .ear suffix or
.ear/ in case of directory deployments.
| // org.jboss.ejb3.Ejb3Module
|
| public Ejb3Module(DeploymentInfo di)
| {
| DeploymentScope deploymentScope = null;
| if (di.parent != null)
| {
| if (di.parent.shortName.endsWith(".ear") ||
di.parent.shortName.endsWith(".ear/"))
| {
| synchronized(di.parent.context)
| {
| deploymentScope =
(DeploymentScope)di.parent.context.get("EJB3_EAR_METADATA");
| if (deploymentScope == null)
| {
| deploymentScope = new JmxDeploymentScopeImpl(di.parent.shortName);
| di.parent.context.put("EJB3_EAR_METADATA",
deploymentScope);
| }
| }
| }
| }
| deployment = new Ejb3JmxDeployment(di, deploymentScope);
| if (deploymentScope != null)
| {
| deploymentScope.register(deployment);
| }
| this.di = di;
| }
|
Looking at this code one might conclude that DeploymentScope stored in parent module
context indicates EAR archive, not the existence of the parent deployment itself.
------
I'm pretty sure that it was not intended to work this way and that it is a bug, but I
would like to see your opinions before I report a bug.
I had to prepare quick workaround, there are modified methods:
Class: org.jboss.wsf.container.jboss42.JAXWSDeployerHookEJB3
Archive: jbossws-jboss42.jar from JBoss AS 4.2.2.GA
Method: createDeployment.
| @Override
| public Deployment createDeployment(DeploymentInfo di)
| {
| ArchiveDeployment dep = newDeployment(di);
| dep.setRootFile(new URLLoaderAdapter(di.localUrl));
| dep.setRuntimeClassLoader(di.ucl);
| dep.setType(getDeploymentType());
|
| Service service = dep.getService();
|
| Ejb3ModuleMBean ejb3Module =
EJBArchiveMetaDataAdapterEJB3.getEJB3Module(di.deployedObject);
| for (Object manager : ejb3Module.getContainers().values())
| {
| if (manager instanceof EJBContainer)
| {
| EJBContainer container = (EJBContainer)manager;
| if (isWebServiceBean(container))
| {
| String ejbName = container.getEjbName();
| String epBean = container.getBeanClassName();
|
| // Get qualified name of the EJB3 module. It is possible to get it
directly from
| // EJBContainer in its original form so I don't see why don't use it.
Are there any
| // contra arguments?
| if( dep instanceof AbstractExtensible ) {
| AbstractExtensible extensible = (AbstractExtensible)dep;
| if( !extensible.getProperties().contains(
"EJB3_QUALIFIED_NAME" ) ) {
| String deploymentQualifiedName = Ejb3Module.BASE_EJB3_JMX_NAME +
"," + container.getDeploymentQualifiedName();
| extensible.setProperty( "EJB3_QUALIFIED_NAME",
deploymentQualifiedName );
| }
| }
|
| // Create the endpoint
| Endpoint ep = newEndpoint(epBean);
| ep.setShortName(ejbName);
| service.addEndpoint(ep);
| }
| }
| }
|
| return dep;
| }
|
Class: org.jboss.wsf.container.jboss42.InvocationHandlerEJB3
Archive: jbossws-jboss42.jar from JBoss AS 4.2.2.GA
Method: init.
| public void init(Endpoint ep)
| {
| String ejbName = ep.getShortName();
| ArchiveDeployment dep = (ArchiveDeployment)ep.getService().getDeployment();
|
| // Try to get qualified name prepared earlier
| String nameStr = null;
| if( dep instanceof AbstractExtensible ) {
| nameStr = (String)((AbstractExtensible)dep).getProperty(
"EJB3_QUALIFIED_NAME" );
| }
|
| if ( nameStr == null ) {
| nameStr = "jboss.j2ee:name=" + ejbName +
",service=EJB3,jar=" + dep.getSimpleName();
| if (dep.getParent() != null)
| {
| nameStr += ",ear=" + dep.getParent().getSimpleName();
| }
| }
|
| objectName = ObjectNameFactory.create(nameStr.toString());
|
| Dispatcher dispatcher = Dispatcher.singleton;
| if (dispatcher.getRegistered(objectName.getCanonicalName()) == null)
| throw new WebServiceException("Cannot find service endpoint target:
" + objectName);
| }
|
Regards,
SÃÂ
ÃÂawomir Wojtasiak
View the original post :
http://www.jboss.com/index.html?module=bb&op=viewtopic&p=4159368#...
Reply to the post :
http://www.jboss.com/index.html?module=bb&op=posting&mode=reply&a...