Hi again,
I thinking about another way to implement my CXF EJB proxy.
In place of using a delegator bean containing the @WebService annotation,
can I use directly the EJB interface (MyServiceSession) and providing a WSDL
descriptor to the cxf-se component ?
At final, the cxf-se component will contain directly the EJB interface (not an
impl
class) and the WSDL corresponding with this interface.
Of course, it's not an agile solution because the WDSL must match the EJB
interface format, but it avoids writing bean impl.
What do you think about this ?
Another way that can be interesting, is to create a object adapter using
dynamic proxy
which looks like this :
import java.lang.reflect.*;
import java.util.*;
public class DynamicObjectAdapterFactory {
public static <T> T adapt(final Object adaptee,
final Class<T> target,
final Object adapter) {
return (T) Proxy.newProxyInstance(
Thread.currentThread().getContextClassLoader(),
new Class[]{target},
new InvocationHandler() {
private Map<MethodIdentifier, Method> adaptedMethods =
new HashMap<MethodIdentifier, Method>();
// initializer block - find all methods in adapter object
{
Method[] methods = adapter.getClass().getDeclaredMethods();
for (Method m : methods) {
adaptedMethods.put(new MethodIdentifier(m), m);
}
}
public Object invoke(Object proxy, Method method,
Object[] args) throws Throwable {
try {
Method other = adaptedMethods.get(
new MethodIdentifier(method));
if (other != null) {
return other.invoke(adapter, args);
} else {
return method.invoke(adaptee, args);
}
} catch (InvocationTargetException e) {
throw e.getTargetException();
}
}
});
}
private static class MethodIdentifier {
private final String name;
private final Class[] parameters;
public MethodIdentifier(Method m) {
name = m.getName();
parameters = m.getParameterTypes();
}
// we can save time by assuming that we only compare against
// other MethodIdentifier objects
public boolean equals(Object o) {
MethodIdentifier mid = (MethodIdentifier) o;
return name.equals(mid.name) &&
Arrays.equals(parameters, mid.parameters);
}
public int hashCode() {
return name.hashCode();
}
}
}
I can add the WebService annotation to the object adapter. But I think that CXF
based on the impl class method definition.
So with this kind of object adapter, CXF will not be able to generate the
correct WSDL (at runtime).
Correct ?
Regards
On Mon 22/09/08 10:40, "Freeman Fang" [EMAIL PROTECTED] wrote:
> Jean-Baptiste Onofré wrote:
> > My purpose is to create a EJB proxy (as we can do
> using JSR181 component) using CXF-SE.
>
> > As I need to define the @WebService annotation in
> the POJO bean used by cxf-se component, I can't do it directly
> using the
> SimpleRemoteStatelessSessionProxyFactoryBean provided by Spring (I can't
> change the implementation of this bean).
>
> > So I need to create a FrontendBean and define the
> call like this in the xbean.xml :
>
> > <bean id="ejbProxy"
> class="org.springframework.ejb.access.SimpleRemoteStatelessSessionProxyFact
> oryBean">
> [...]
> > </bean>
> >
> > <cxfse:pojo>
> > <bean
> class="my.package.FrontendBean">
> <property name="proxy"
> ref="ejbProxy"/>
> </bean>
> > </cxfse:pojo>
> >
> > The FrontendBean will define the same methods as the
> EJB, and the implementation of each methods will call the EJB side using
> the Spring proxy.
>
> > Is CXF will be able to generate the WDSL dynamically
> using the POJO (and the POJO methods) or should I create my own one
> manually ?
> Is this solution correct ?
> >
> Cxf will generate the wsdl on the fly
> > Maybe it can be interesting to create a
> documentation how to define a EJB proxy using CXF-SE (I can write one if
> you want when my test case will be completed :)).
>
> Looking forward to the document
> > Regards
> >
> > On Mon 22/09/08 09:17, "Freeman Fang" freema
> [EMAIL PROTECTED] wrote:
>
> >> Jean-Baptiste Onofré wrote:
> >>
> >>> Hi all,
> >>>
> >>> I have setup an SU like this (in the
> xbean.xml)
>>>
> >> :
> >>
> >>
> >>> <beans xmlns:cxfse="http://servicemix.apache.org/cxfse/1.0"
>>>> xmlns:fsb="http://www.fimasys.com/fsb">
>>>>
> >>> <bean
> >>>
> >>
> class="org.springframework.beans.factory.config.PropertyPlaceholderConfigur
>
>> er">
> >> <property
> name="locations">
>>
> >>>
> >>>
> >>
> <value>classpath:/automatic-validation-service-config.properties</
>
>> value>
> >> </property>
> >>
> >>> </bean>
> >>>
> >>> <bean id="jndiTemplate"
> >>>
> >>
> class="org.springframework.jndi.JndiTemplate">
>> <property
> >> name="environment">
> >> <props>
> >>
> >>> <prop
> >>>
> >>
> key="java.naming.factory.initial">
>>
> ${bos.jndiContextFactory}
>>
> >>> </prop>
> >>> <prop
> >>>
> >> key="java.naming.provider.url">
> >>
> ${bos.jndiUrlProvider}
>>
> >>> </prop>
> >>> </props>
> >>> </property>
> >>> </bean>
> >>>
> >>> <cxfse:endpoint
> >>>
> >>
> service="automatic-validation-service-proxy">
>> <cxfse:pojo>
> >>
> >>> <bean
> >>>
> >>
> class="org.springframework.ejb.access.SimpleRemoteStatelessSessionProxyFact
>
>> oryBean">
> >> <property
> name="jndiName"
>>
> value="ejb/profinance/back-office/AutomaticSimulationSession"/>
>> <property
> name="businessInterface"
>>
> value="com.fimasys.finance.profinance.components.simulation.common.ejb.Auto
>
>> maticSimulationSession"/>
> >> <property
> name="homeInterface"
>>
> value="com.fimasys.finance.profinance.components.simulation.common.ejb.Auto
>
>> maticSimulationSessionHome"/>
> >> <property
> >> name="refreshHomeOnConnectFailure"
> value="true"/>
>> <property
> name="cacheHome"
>> value="true"/>
> >> <property
> name="lookupHomeOnStartup"
>> value="true"/>
> >> <property
> name="resourceRef"
>> value="false"/>
> >> <property
> name="jndiTemplate"
>> ref="jndiTemplate"/>
> >> </bean>
> >>
> >>> </cxfse:pojo>
> >>> </cxfse:endpoint>
> >>>
> >>> </beans>
> >>>
> >>> In the SU POM dependencies, I have added
> all
>>>
> >> required jar (the jbossall-client providing the
> JNDI context, the Spring
>> context to have the
> SimpleRemoteStatelessSessionProxyFactoryBean and my
>> application client to have the stub, home and
> remote
>> interface).
> >>
> >>
> >>> When I deploy the SA which embed this SU, I
> have
>>>
> >> this stack trace :
> >>
> >>
> >>>
>
>>>
> >>
> <stack-trace><![CDATA[java.lang.NullPointerException
>> at
> >>
> org.apache.cxf.jaxws.support.JaxWsImplementorInfo.getWSInterfaceName(JaxWsI
>
>> mplementorInfo.java:235)
> >> at
> >>
> org.apache.cxf.jaxws.support.JaxWsImplementorInfo.initialise(JaxWsImplement
>
>> orInfo.java:274)
> >> at
> >>
> org.apache.cxf.jaxws.support.JaxWsImplementorInfo.<init>(JaxWsImpleme
>
>> ntorInfo.java:57)
> >> at
> >>
> org.apache.cxf.jaxws.EndpointImpl.getServer(EndpointImpl.java:269)
>> at
> >>
> org.apache.cxf.jaxws.EndpointImpl.getServer(EndpointImpl.java:261)
>> at
> >>
> org.apache.servicemix.cxfse.CxfSeEndpoint.start(CxfSeEndpoint.java:243)
>> at
> >>
> org.apache.servicemix.common.endpoints.SimpleEndpoint.activate(SimpleEndpoi
>
>> nt.java:55)
> >> at
> >>
> org.apache.servicemix.common.ServiceUnit.start(ServiceUnit.java:53)
> >>
> >>> at
> >>>
> >>
> org.apache.servicemix.common.BaseServiceUnitManager.start(BaseServiceUnitMa
>
>> nager.java:151)
> >> at
> >>
> org.apache.servicemix.jbi.framework.ServiceUnitLifeCycle.start(ServiceUnitL
>
>> ifeCycle.java:103)
> >> at
> >>
> org.apache.servicemix.jbi.framework.ServiceAssemblyLifeCycle.start(ServiceA
>
>> ssemblyLifeCycle.java:132)
> >> at
> >>
> org.apache.servicemix.jbi.framework.DeploymentService.start(DeploymentServi
>
>> ce.java:378)
> >> at
> >>
> org.apache.servicemix.jbi.framework.AutoDeploymentService.updateServiceAsse
>
>> mbly(AutoDeploymentService.java:355)
> >> at
> >>
> org.apache.servicemix.jbi.framework.AutoDeploymentService.updateArchive(Aut
>
>> oDeploymentService.java:256)
> >> at
> >>
> org.apache.servicemix.jbi.framework.AutoDeploymentService.updateExternalArc
>
>> hive(AutoDeploymentService.java:204)
> >> at
> >>
> org.apache.servicemix.jbi.container.JBIContainer.updateExternalArchive(JBIC
>
>> ontainer.java:476)
> >> at
> >>
> org.apache.servicemix.jbi.container.JBIContainer.updateExternalArchive(JBIC
>
>> ontainer.java:486)
> >> at
> >>
> org.apache.servicemix.jbi.framework.AdminCommandsService.deployServiceAssem
>
>> bly(AdminCommandsService.java:209)
> >> [...]
> >>
> >>> Asking on the IRC, the WSDL descriptor is
> not
>>>
> >> required.
> >>
> >>
> >>> Should I provide a kind of ServiceImpl
> defining
>>>
> >> @WebService annotation ?
> >>
> >>
> >>>
> >>>
> >> Yes, you need define @WebService annotation for
> your Impl class
>>
> >>> Thanks
> >>> Regards
> >>>
> >>>
> >>
> >>
> >>
> >
> >
> >
>
>
>
>