What I'm going to show is experimental. If you have the spring jar in
WEB-INF/lib and only one AAR, it seems to work. Multiple AAR's still
need to be tested. Furthermore, I'm hoping axis2-1033 when resolved
will avoid the need for a Spring init service.
Have your AAR like so:
./springExample.aar
./META-INF
./META-INF/MANIFEST.MF
./META-INF/services.xml
./applicationContext.xml
./spring
./spring/MyBean.class
./spring/MyBeanImpl.class
./spring/SpringAwareService.class
./spring/SpringInit.class
services.xml is:
<serviceGroup>
<service name="SpringInit">
<description>
Spring init
</description>
<parameter name="ServiceClass" locked="false">spring.SpringInit</parameter>
<operation name="springInit">
<messageReceiver
class="org.apache.axis2.receivers.RawXMLINOutMessageReceiver"/>
</operation>
</service>
<service name="SpringAwareService">
<description>
simple spring example
</description>
<parameter name="ServiceObjectSupplier"
locked="false">org.apache.axis2.extensions.spring.receivers.SpringAppContextAwareObjectSupplier</parameter>
<parameter name="SpringBeanName"
locked="false">springAwareService</parameter>
<operation name="getValue">
<messageReceiver
class="org.apache.axis2.receivers.RawXMLINOutMessageReceiver"/>
</operation>
</service>
</serviceGroup>
The Spring init service follows - the rest is based on the tutorial:
package spring;
import org.apache.axiom.om.OMAbstractFactory;
import org.apache.axiom.om.OMElement;
import org.apache.axiom.om.OMFactory;
import org.apache.axiom.om.OMNamespace;
import org.apache.axiom.om.OMText;
import org.apache.axis2.engine.Service;
import org.apache.axis2.context.ConfigurationContext;
import org.apache.axis2.context.OperationContext;
import org.apache.axis2.context.ServiceContext;
import org.apache.axis2.description.AxisService;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
public class SpringInit implements Service {
private static Log logger = LogFactory
.getLog(SpringInit .class);
// The web service
public OMElement springInit(OMElement ignore) {
OMFactory factory=
OMAbstractFactory.getOMFactory();
OMNamespace payloadNs= factory.createOMNamespace(
"http://springExample.org/example1", "example1");
OMElement payload =
factory.createOMElement("string", payloadNs);
OMText response = factory.createOMText("Spring did application
context init");
payload.addChild(response);
return payload;
}
/*
*/
public void init(ServiceContext serviceContext) {
AxisService axisService = serviceContext.getAxisService();
ClassLoader classLoader = axisService.getClassLoader();
ClassPathXmlApplicationContext ctx = new
ClassPathXmlApplicationContext(new String[]
{"applicationContext.xml"}, false);
ctx.setClassLoader(classLoader);
ctx.refresh();
if (logger.isDebugEnabled()) {
logger.debug("\n\ninit() set spring classloader via
axisService.getClassLoader() ... ");
}
}
public void setOperationContext(OperationContext arg0) {
}
public void destroy(ServiceContext arg0) {
}
}
You need to call the spring init client for now:
package client;
import java.io.StringWriter;
import javax.xml.stream.XMLOutputFactory;
import org.apache.axiom.om.OMAbstractFactory;
import org.apache.axiom.om.OMElement;
import org.apache.axiom.om.OMFactory;
import org.apache.axiom.om.OMNamespace;
import org.apache.axis2.addressing.EndpointReference;
import org.apache.axis2.client.Options;
import org.apache.axis2.client.ServiceClient;
public class SpringInitClient {
/** Access point inside the servlet container. **/
private static EndpointReference targetEPR =
new EndpointReference(
// "http://localhost:8080/axis2/services/springExample");
"http://localhost:9080/axis2/services/SpringInit");
/**
* Simple axis2 client.
*
* @param args Main
*/
public static void main(String[] args) {
try {
OMFactory factory = OMAbstractFactory.getOMFactory();
OMNamespace omNs = factory.createOMNamespace(
"http://springExample.org/example1", "example1");
OMElement method = factory.createOMElement("springInit", omNs);
OMElement value = factory.createOMElement("Text", omNs);
value.addChild(factory.createOMText(value, "Some String "));
method.addChild(value);
ServiceClient serviceClient = new ServiceClient();
Options options = new Options();
serviceClient.setOptions(options);
options.setTo(targetEPR);
//Blocking invocation
OMElement result = serviceClient.sendReceive(method);
StringWriter writer = new StringWriter();
result.serialize(XMLOutputFactory.newInstance()
.createXMLStreamWriter(writer));
writer.flush();
System.out.println("Response: " + writer.toString());
} catch (Exception ex) {
ex.printStackTrace();
}
}
}
I'll be working thru the rest of the classloader issues mentioned as
time permits.
HTH,
Robert
http://www.braziloutsource.com/
On 8/24/06, Declan Dunleavy <[EMAIL PROTECTED]> wrote:
Hi Robert,
I am happy to load spring.jar from the Axis2/WEB-INF/lib folder.
cheers,
Declan
----- Original Message ----
From: robert lazarski <[EMAIL PROTECTED]>
To: [email protected]
Sent: Wednesday, 23 August, 2006 11:53:05 PM
Subject: Re: Axis2 and Spring: Preserving Service Isolation
Yes, the spring docs are focused so far on the simpler cases.
Configuring spring via na AAR isn't documented yet as I need to do
more testing, but to asnswer your question I need to know where do you
want to load the spring.jar from , inside the AAR or WEB-INF/lib ?
If the spring.jar is loaded from WEB-INF/lib , that's no problem and I
can show you how to load your applicationContext.xml / beanRef.xml
from the aar to configure Spring and you can use the
ServiceObjectSupplier method to wire your beans as explained in the
docs. One caveat: I need to test this with multiple AAR's, but my
initial tests shows that it can work for one AAR .
If the spring.jar is loaded inside the AAR , you still can load your
applicationContext.xml from the aar. I'm still thinking thru, however,
if you wanted to how you could use the ServiceObjectSupplier in that
case . That's because the Spring ApplicationContext object, in the
spring jar inside the aar case , will not be visible at the
WEB-INF/lib level where the AbstractMessageReceiver will attempt to
wire the bean. There's probably a solution here but I still need to
think it thru.
In the case of the latter, perhaps I can get
AxisService.getClassLoader() at the ServiceObjectSupplier /
AbstracMessageReceiver level to get the spring ApplicationContext
object (not the xml file) from the AAR/lib/spring.jar , though that
may not work in terms of classloader isolation. Someone such as Dims
or Deepal may be able to comment .
In any case, the solution at the service level will involve the
service implementing the org.apache.axis2.engine.Service interface
and doing the spring config in init() . There is a blocker for the
next release, axis2-1033, that when resolved will permit init() to be
called on server startup much like a servlet load on startup. My
spring inside an aar tests have been calling a service first that
configures spring until axis2-1033 is resolved. Once you let me know
which scenario you have in mind I'll work with you to get it
implemented.
Cheers,
Robert
http://www.braziloutsource.com/
On 8/23/06, Declan Dunleavy <[EMAIL PROTECTED]> wrote:
>
>
>
> Hi,
>
>
> I emailed Robert Lazarski to get more information about integrating Axis2
> with Spring, to which he helpfully pointed me to the following solution:
>
> > Spring support is in the nightlies:
> >
> > http://people.apache.org/dist/axis2/nightly/
> >
> > Its documented here:
> >
> >
>
http://svn.apache.org/repos/asf/webservices/axis2/trunk/java/xdocs/latest/spring.html
>
> This solution outlined here requires the Spring applicationContext.xml to
> live outside the AAR service file in the Axis2 WEB-INF folder and is
> configured within the web.xml, which is not as modular as I would like.
>
> I was wondering if there's any way to preserve service isolation by
> incorporating the ApplicationContext.xml / BeanFactory.xml inside the AAR.
> As I would prefer not to have to update the axis2 WEB-INF folder
> applicationContext.xml file with updates to the AARs bean classes every
time
> I release new code. I wasn't sure if it was possible but thought I'd ask
> Robert anyway. He suggested I post the question here.
>
> Thanks in advance for any replies,
>
> Declan
>
>
>
>
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]