[Design of JBoss Web Services] - Re: JBMETA-44, ws annotation processing for references
by alessio.soldano@jboss.com
"alex.loubyansky(a)jboss.com" wrote : I've modified the WebServiceRefHandler to add injectors to the container. http://jira.jboss.com/jira/browse/EJBTHREE-1424 So, the JBCTS-797 now passes with the latest not yet released EJB3 and metadata versions.
|
| Another issue in the ClientContainer was that the AnnotatedElement was lost during serialization. So, sref.getInjectionTargets() had to be used instead.
As far as I understand, the commit you're talking about is http://fisheye.jboss.com/browse/JBossAS/projects/ejb3/trunk/core/src/main....
Is this included in the current 0.1.5-SNAPSHOT? I'm asking because I've updated my local environment to use it and my jbossws testcases fail with this:
| ...
| Caused by: java.lang.IllegalStateException: Annotated element for 'env/Service1' is niether Method nor Field: class org.jboss.test.ws.jaxws.webserviceref.TestEndpointClientTwo
| at org.jboss.injection.WebServiceRefHandler.addInjector(WebServiceRefHandler.java:113)
| at org.jboss.injection.WebServiceRefHandler.loadXml(WebServiceRefHandler.java:82)
| at org.jboss.ejb3.clientmodule.ClientENCInjectionContainer.processMetaData(ClientENCInjectionContainer.java:319)
| at org.jboss.ejb3.clientmodule.ClientENCInjectionContainer.<init>(ClientENCInjectionContainer.java:164)
| at org.jboss.ejb3.deployers.Ejb3ClientDeployer.deploy(Ejb3ClientDeployer.java:122)
|
I guess that's because the service class is something like this:
| @WebServiceRef(name = "Service1")
| // Test multiple on type
| @WebServiceRefs( { @WebServiceRef(name = "Service2"), @WebServiceRef(name = "Port1", type = TestEndpoint.class) })
| public class TestEndpointClientTwo
| {
| // provide logging
| private static final Logger log = Logger.getLogger(org.jboss.test.ws.jaxws.webserviceref.TestEndpointClientTwo.class);
|
| // Test on field
| @WebServiceRef(name = "Service3")
| static Service service3;
| ...
|
i.e. it has @WebServiceRef on the class too.
Hope this helps
Thanks
View the original post : http://www.jboss.com/index.html?module=bb&op=viewtopic&p=4159373#4159373
Reply to the post : http://www.jboss.com/index.html?module=bb&op=posting&mode=reply&p=4159373
15 years, 11 months
[Design of JBoss Web Services] - Nested EJB3 modules deployment process and JBossWS.
by slawomir.wojtasiak
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#4159368
Reply to the post : http://www.jboss.com/index.html?module=bb&op=posting&mode=reply&p=4159368
15 years, 11 months
[Design of JBoss Web Services] - Re: JBMETA-44, ws annotation processing for references
by alessio.soldano@jboss.com
I'm running some test cases on JBossWS side to validate the JBMETA-44 and I've just come to this:
"alex.loubyansky(a)jboss.com" wrote : Another question related to JBMETA-44 and JBCTS-797. It's not clear to me how the @WebServiceRef should be mapped to ServiceReferenceMetaData.
|
| What (if anything) in @WebServiceRef should specify the service-interface?
|
| The current processing of @WebServiceRef is
| if(annotation.type() != Object.class)
| | ref.setServiceRefType(annotation.type().getName());
| | else
| | ref.setServiceRefType(getType(element));
| | if(annotation.value() != Object.class)
| | ref.setServiceInterface(annotation.value().getName());
| |
|
| Is this correct? The example Scott posted above is from JBCTS-797 which currently fails because "service-interface is null".
|
Yes, as Thomas said, this should be the right implementation.
I've just seen that commit 74508 changed the implementation to:
| if(annotation.type() != Object.class)
| ref.setServiceRefType(annotation.type().getName());
| else
| ref.setServiceRefType(getType(element));
| if(annotation.value() != Object.class)
| ref.setServiceInterface(annotation.value().getName());
| else
| ref.setServiceInterface(ref.getServiceRefType());
|
In my opinion this is not right since you might end up having the SEI class name in the serviceInterface attribute in cases where a reference whose type is a SEI is defined.
The above change was done because of the "<service-interface> cannot be null" error at the beginning of this thread that actually proved to be caused by the annotatedElement not being set, wan't it?
Thanks
View the original post : http://www.jboss.com/index.html?module=bb&op=viewtopic&p=4159286#4159286
Reply to the post : http://www.jboss.com/index.html?module=bb&op=posting&mode=reply&p=4159286
15 years, 11 months