cancel
Showing results for 
Search instead for 
Did you mean: 

Cannot inject Web Service Proxy in EJB by using @WebServiceRef

markus_muenkel
Associate
Associate
0 Kudos

Hi,

I have created a Web Service Proxy project in NWDI and deployed it to a NW 7.1 AS Java. As a result, it is listed in NW Admin "SOA Management" -> "Web Services Administration" under "Proxy Definitions" as expected.

There the details in tab "General" show:

State: With Logical Ports

Namespace: http://sap.com/xi/APPL/SE/Global

WSDL Porttype Name: OutboundDeliveryByIDQueryResponse_In

Internal Name: 1daacd1d:11873e1023a:-7fff_OutboundDeliveryByIDQueryResponse_In

Now I would like to use this proxy in a session EJB. This EJB is contained in a NWDI EJB project, which is referencing the Web Service Proxy project via public part. My approach was to use injection via the @WebServiceRef annotation in the EJB. To this end, I guess I need to specify the JNDI name of the web service proxy. It is a similar approach as described in the paper [Service Registry for ESWorkplace |https://www.sdn.sap.com/irj/sdn/go/portal/prtroot/docs/library/uuid/501668ab-976e-2a10-91b6-c1020e8c54f2] .

Question: if this approach is correct, how can I find out what's the JNDI name to use in the "name" property of the @WebServiceRef annotation?

I also tried

@WebServiceRef(name="OutboundDeliveryByIDQueryResponse_In")

OutboundDeliveryByIDQueryResponse_InService obj;

but the factory could not inject the resource at runtime.

Thanks a lot for your help!

Regards,

Markus

Accepted Solutions (1)

Accepted Solutions (1)

Vlado
Advisor
Advisor
0 Kudos

Hi Markus,

The name attribute specifies the local name used to bind the resource in the java:comp/env ENC of the EJB. But since (I guess) you don't use JNDI lookup and instead rely on DI, this name doesn't matter actually. It's also an optional attribute, you may safely leave it out.

Do you still get an exception in that case? If yes, please post its stack trace.

HTH!

\-- Vladimir

markus_muenkel
Associate
Associate
0 Kudos

Hi Vladimir,

since the stack trace is very large I'm attaching the portion that seems to be the crucial one:

Caused by: com.sap.engine.lib.injection.InjectionException: Injection on field obj of instance com.sap.rwa.ejb.ErpDocumentBean@192ff0c failed. Could not get a value to be injected from the factory.

at com.sap.engine.lib.injection.FieldInjector.inject(FieldInjector.java:115)

at com.sap.engine.lib.injection.InjectionMatrix.inject(InjectionMatrix.java:45)

at com.sap.engine.services.ejb3.runtime.impl.Interceptors_DependencyInjection.invoke(Interceptors_DependencyInjection.java:22)

... 111 more

Caused by: java.lang.InstantiationException: com.sap.rwa.collection.OutboundDeliveryByIDQueryResponse_InService

at java.lang.Class.newInstance0(Class.java:335)

at java.lang.Class.newInstance(Class.java:303)

at com.sap.engine.interfaces.webservices.server.wsclient.ServiceObjectFactory.getObjectInstance(ServiceObjectFactory.java:75)

at com.sap.engine.lib.injection.ReferenceObjectFactory.getObject(ReferenceObjectFactory.java:65)

at com.sap.engine.lib.injection.FieldInjector.inject(FieldInjector.java:113)

... 113 more

What apparently happens is that the annotation

@WebServiceRef(name="OutboundDeliveryByIDQueryResponse_In")

OutboundDeliveryByIDQueryResponse_InService obj;

tries to instantiate OutboundDeliveryByIDQueryResponse_InService, which is in fact an interface. Therefore injection fails with an InstantiationException. What I seem to be missing is a reference to the Web Service Proxy for enterprise service "OutboundDeliveryByIDQueryResponse_In", which is deployed in the engine.

Best Regards,

Markus

Vlado
Advisor
Advisor
0 Kudos

Well, the WebServiceRef documentation says:

public abstract java.lang.Class value
The service class, always a type extending javax.xml.ws.Service. This element MUST be specified whenever the type of the reference is a service endpoint interface.

javax.xml.ws.Service is a class, not an interface. So, you definitely seem to be missing sth.

Are you trying to inject a reference to a proxy for a specific service endpoint interface, or to a Service class?

Cheers,

\-- Vladimir

Answers (4)

Answers (4)

markus_muenkel
Associate
Associate
0 Kudos

Hi Dimitar,

it is not possible to specify the class as type of the object that is to be injected. The type OutboundDeliveryByIDQueryResponse_InService is in fact an interface, not a service class. Note that the deployable WS Proxy exposes interfaces only for the design-time.

I would expect injection to work nevertheless, in analogy to @EJB injection:

@EJB

MyEjbLocalInterface myEjb;

Here the container injects an EJB object in myEjb even though the type MyEjbLocalInterface is an interface.

Best regards,

Markus

0 Kudos

Hi,

The JAX-WS proxy artefact contain:

1. Service class which extends javax.xml.ws.Service

2. Service Endpoint Interface

3. Additianal JAXB classes depending if there is XSD constructs in the WSDL

In the injection below, the type of the field 'obj' should be the service class, rather the interface. Once the service object is inject you should used some of its getXXPort() method(s) to obtain service endpoint interface on which to call ws business methods.

@WebServiceRef(name="OutboundDeliveryByIDQueryResponse_In")

OutboundDeliveryByIDQueryResponse_InService obj;

Hope this helps.

~Dimitar

markus_muenkel
Associate
Associate
0 Kudos

Hi Vladimir,

so the issue boils down to the question:

Suppose

- I have the full JNDI name of a deployed Web Service Proxy

- I don't have the implementing class but an interface

- I wish to use dependency injection based on the JNDI name

how then should I proceed? Again, it seems to be the same thing as in the example on page 35 in the paper [Service Registry for ESWorkplace |https://www.sdn.sap.com/irj/sdn/go/portal/prtroot/docs/library/uuid/501668ab-976e-2a10-91b6-c1020e8c54f2].

Cheers,

Markus

markus_muenkel
Associate
Associate
0 Kudos

Hi Vladimir,

meanwhile I tried to get the web service reference by direct JNDI lookup. The following works fine:

<My_Service_Type> service = (<My_Service_Type>) ctx.lookup("/wsclients/proxies/<vendor>/<WD Proxy DC name>/<WS Proxy name>");

whereby <My_Service_Type> is an interface.

However when I try to achieve the same by the annotation

@WebServiceRef(name="/wsclients/proxies/<vendor>/<WD Proxy DC name>/<WS Proxy name>")

<My_Service_Type> service;

this produces a deploy exception that the resource could not be injected (without further information in the trace).

Since the JavaDoc says

public abstract String name: The JNDI name of the resource

I hoped that I could just pass the JNDI name of the WS proxy to the @WebServiceRef and injection should work. The JNDI name seems to be correct since everything works with direct context lookup. Am I still missing something?

Cheers,

Markus

Vlado
Advisor
Advisor
0 Kudos

Hi Markus,

Please refer to my previous reply about the name attribute. It's not the global JNDI name of the resource as you seem to be assuming. However, as I already mentioned, this should bear no connection to the injection.

Apparently you're trying to obtain a reference to a WS proxy (SEI). In this case, as the JavaDoc states, you have to specify the WS Service in the value attribute.

HTH!

\-- Vladimir