You are viewing a plain text version of this content. The canonical link for it is here.
Posted to java-dev@axis.apache.org by sc...@apache.org on 2006/11/18 17:58:26 UTC
svn commit: r476565 - in /webservices/axis2/trunk/java/modules/jaxws:
src/org/apache/axis2/jaxws/message/databinding/
src/org/apache/axis2/jaxws/server/ src/org/apache/axis2/jaxws/util/
test/org/apache/axis2/jaxws/proxy/
Author: scheu
Date: Sat Nov 18 08:58:26 2006
New Revision: 476565
URL: http://svn.apache.org/viewvc?view=rev&rev=476565
Log:
AXIS2-1730
Contributor: Rich Scheuerle (WSDL author by Lizet Ernand)
More RPC tests, fixes to getClassesFromPackage logic to include array classes, fix to JAXWSMessageReceiver to throw an AxisFault when problems occur.
Modified:
webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/message/databinding/JAXBUtils.java
webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/server/JAXWSMessageReceiver.java
webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/util/ClassUtils.java
webservices/axis2/trunk/java/modules/jaxws/test/org/apache/axis2/jaxws/proxy/RPCProxyTests.java
Modified: webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/message/databinding/JAXBUtils.java
URL: http://svn.apache.org/viewvc/webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/message/databinding/JAXBUtils.java?view=diff&rev=476565&r1=476564&r2=476565
==============================================================================
--- webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/message/databinding/JAXBUtils.java (original)
+++ webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/message/databinding/JAXBUtils.java Sat Nov 18 08:58:26 2006
@@ -16,8 +16,14 @@
*/
package org.apache.axis2.jaxws.message.databinding;
+import java.io.File;
+import java.io.IOException;
+import java.io.UnsupportedEncodingException;
+import java.net.URL;
+import java.net.URLDecoder;
import java.util.ArrayList;
import java.util.Collections;
+import java.util.Enumeration;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
@@ -30,6 +36,7 @@
import javax.xml.bind.Marshaller;
import javax.xml.bind.Unmarshaller;
+import org.apache.axis2.jaxws.i18n.Messages;
import org.apache.axis2.jaxws.message.databinding.impl.JAXBBlockImpl;
import org.apache.axis2.jaxws.util.ClassUtils;
import org.apache.commons.logging.Log;
@@ -60,6 +67,7 @@
private static boolean ENABLE_ADV_POOLING = false;
+
/**
* Get a generic JAXBContext (that can be used for primitives)
* @throws JAXBException
@@ -96,14 +104,50 @@
if (context == null) {
synchronized(map) {
try{
- Iterator<Package> it = contextPackages.iterator();
- List<Class> fullList = new ArrayList<Class>();
- while (it.hasNext()) {
- Package pkg = it.next();
- fullList.addAll(ClassUtils.getAllClassesFromPackage(pkg));
- }
- Class[] classArray = fullList.toArray(new Class[0]);
- context = JAXBContext.newInstance(classArray);
+ // There are two ways to construct the context.
+ // 1) USE A CONTEXTPATH, which is a string containing
+ // all of the packages separated by colons.
+ // 2) USE A CLASS[], which is an array of all of the classes
+ // involved in the marshal/unmarshal.
+ //
+ // There are pros/cons with both approaches.
+ // USE A CONTEXTPATH:
+ // Pros: preferred way of doing this.
+ // performant
+ // most dynamic
+ // Cons: Each package in context path must have an ObjectFactory
+ // Problems with RPC types
+ //
+ // USE CLASS[]:
+ // Pros: Doesn't require ObjectFactory in each package
+ // Cons: Hard to set up, must account for JAX-WS classes, etc.
+ // Does not work if arrays of classes are needed
+ // slower
+ //
+ // The following code attempts to build a context path. It then
+ // choose one of the two constructions above (prefer USE A CONTEXT_PATH)
+ //
+
+ // REVIEW: DISABLE UNTIL ARRAY PROBLEMS WITH RPC ARE DIAGNOSED
+ //context = createJAXBContextUsingContextPath(contextPackages);
+
+ if (context == null) {
+ // Unsuccessful, USE CLASS[]
+ if (log.isDebugEnabled()) {
+ log.debug("Attempting to create JAXBContext with Class[]");
+ }
+ Iterator<Package> it = contextPackages.iterator();
+ List<Class> fullList = new ArrayList<Class>();
+ while (it.hasNext()) {
+ Package pkg = it.next();
+ fullList.addAll(JAXBUtils.getAllClassesFromPackage(pkg));
+ }
+ Class[] classArray = fullList.toArray(new Class[0]);
+ context = JAXBContext.newInstance(classArray);
+ if (log.isDebugEnabled()) {
+ log.debug("Successfully created JAXBContext with Class[] = " + context.toString());
+ }
+ }
map.put(contextPackages, context);
}catch(ClassNotFoundException e){
throw new JAXBException(e);
@@ -247,4 +291,198 @@
}
imap.put(context, introspector);
}
+
+ /**
+ * Create a JAXBContext using the contextpath approach
+ * @param packages
+ * @return JAXBContext or null if unsuccessful
+ */
+ private static JAXBContext createJAXBContextUsingContextPath(Set<Package> packages) {
+ JAXBContext context = null;
+ String contextpath = "";
+
+ // TODO
+ // Do we want to use the current class loader, or get it from a loaded class ?
+ ClassLoader cl = Thread.currentThread().getContextClassLoader();
+
+ // Iterate through the classes and build the contextpath
+ Iterator<Package> it = packages.iterator();
+ while(it.hasNext()) {
+ Package p = it.next();
+ if (p.getName().startsWith("java.") ||
+ p.getName().startsWith("javax.")) {
+ ; // Assume that these packages don't have an object factory
+ } else {
+ // REVIEW
+ // There are two paths here.
+ // A) We could blindly add this package to the contextpath
+ // The JAXBContext construction will fail if the ObjectFactory is
+ // not found
+ // B) We can look for an ObjectFactory in the package and only
+ // add the package if the ObjectFactory is found
+ // I am choosing (A) because choosing (B) may delay an exception
+ // until we are marshalling/unmarshalling an object.
+ if (contextpath.length() != 0) {
+ contextpath +=":";
+ }
+ contextpath += p.getName();
+ }
+ }
+ try {
+ if (log.isDebugEnabled()) {
+ log.debug("Attempting to create JAXBContext with contextPath=" + contextpath);
+ }
+ context = JAXBContext.newInstance(contextpath, cl);
+ if (log.isDebugEnabled()) {
+ log.debug(" Successfully created JAXBContext:" + context);
+ }
+ } catch (Exception e) {
+ if (log.isDebugEnabled()) {
+ log.debug(" Unsuccessful: We will now use an alterative JAXBConstruct construction");
+ log.debug(" Reason " + e.toString());
+ }
+ }
+ return context;
+ }
+
+ /**
+ * This method will return all the Class names needed to construct a JAXBContext
+ * @param pkg Package
+ * @return
+ * @throws ClassNotFoundException
+ */
+ private static List<Class> getAllClassesFromPackage(Package pkg) throws ClassNotFoundException {
+ if (pkg == null) {
+ return new ArrayList<Class>();
+ }
+ // This will hold a list of directories matching the pckgname. There may be more than one if a package is split over multiple jars/paths
+ String pckgname = pkg.getName();
+ ArrayList<File> directories = new ArrayList<File>();
+ try {
+ ClassLoader cld = Thread.currentThread().getContextClassLoader();
+ if (cld == null) {
+ if(log.isDebugEnabled()){
+ log.debug("Unable to get class loader");
+ }
+ throw new ClassNotFoundException(Messages.getMessage("ClassUtilsErr1"));
+ }
+ String path = pckgname.replace('.', '/');
+ // Ask for all resources for the path
+ Enumeration<URL> resources = cld.getResources(path);
+ while (resources.hasMoreElements()) {
+ directories.add(new File(URLDecoder.decode(resources.nextElement().getPath(), "UTF-8")));
+ }
+ } catch (UnsupportedEncodingException e) {
+ if(log.isDebugEnabled()){
+ log.debug(pckgname + " does not appear to be a valid package (Unsupported encoding)");
+ }
+ throw new ClassNotFoundException(Messages.getMessage("ClassUtilsErr2", pckgname));
+ } catch (IOException e) {
+ if(log.isDebugEnabled()){
+ log.debug("IOException was thrown when trying to get all resources for "+ pckgname);
+ }
+ throw new ClassNotFoundException(Messages.getMessage("ClassUtilsErr3", pckgname));
+ }
+
+ ArrayList<Class> classes = new ArrayList<Class>();
+ // For every directory identified capture all the .class files
+ for (File directory : directories) {
+ if (log.isDebugEnabled()) {
+ log.debug("Adding classes from: " + directory.getName());
+ }
+ if (directory.exists()) {
+ // Get the list of the files contained in the package
+ String[] files = directory.list();
+ for (String file : files) {
+ // we are only interested in .class files
+ if (file.endsWith(".class")) {
+ // removes the .class extension
+ // TODO Java2 Sec
+ String className = pckgname + '.' + file.substring(0, file.length() - 6);
+ try {
+ Class clazz = Class.forName(className,
+ false,
+ Thread.currentThread().getContextClassLoader());
+ // Don't add any interfaces or JAXWS specific classes.
+ // Only classes that represent data and can be marshalled
+ // by JAXB should be added.
+ if(!clazz.isInterface()
+ && ClassUtils.getDefaultPublicConstructor(clazz) != null
+ && !ClassUtils.isJAXWSClass(clazz)){
+ if (log.isDebugEnabled()) {
+ log.debug("Adding class: " + file);
+ }
+ classes.add(clazz);
+
+ // REVIEW:
+ // Support of RPC list (and possibly other scenarios) requires that the array classes should also be present.
+ // This is a hack until we can determine how to get this information.
+
+ // The arrayName and loadable name are different. Get the loadable
+ // name, load the array class, and add it to our list
+ className += "[]";
+ String loadableName = ClassUtils.getLoadableClassName(className);
+
+ Class aClazz = Class.forName(loadableName, false, Thread.currentThread().getContextClassLoader());
+ }
+ } catch (Exception e) {
+ if (log.isDebugEnabled()) {
+ log.debug("Tried to load class " + className + " while constructing a JAXBContext. This class will be skipped. Processing Continues." );
+ log.debug(" The reason that class could not be loaded:" + e.toString());
+ }
+ e.printStackTrace();
+ }
+
+ }
+ }
+
+ // REVIEW Load and add the common array classes
+ // Support of RPC list (and possibly other scenarios) requires that the array classes should also be present.
+ // This is a hack until we can determine how to get this information.
+ addCommonArrayClasses(classes);
+ }
+ }
+ return classes;
+ }
+
+ private static String[] commonArrayClasses = new String[] {
+ // primitives
+ "boolean[]",
+ "byte[]",
+ "char[][]",
+ "double[]",
+ "float[]",
+ "int[]",
+ "long[]",
+ "short[]",
+ "java.lang.String[]",
+ // Others
+ "java.lang.Object[]",
+ "java.awt.Image[]",
+ "java.math.BigDecimal[]",
+ "java.math.BigInteger[]",
+ "java.util.Calendar[]",
+ "javax.xml.namespace.QName[]" };
+
+ private static void addCommonArrayClasses(List<Class> list) {
+ // Add common primitives arrays (necessary for RPC list type support)
+ ClassLoader cl = Thread.currentThread().getContextClassLoader();
+
+
+ for (int i=0; i<commonArrayClasses.length; i++) {
+ String className = commonArrayClasses[i];
+ try {
+ // Load and add the class
+ Class cls = Class.forName(ClassUtils.getLoadableClassName(className), false, cl);
+ list.add(cls);
+ } catch (Exception e) {
+ if (log.isDebugEnabled()) {
+ log.debug("Tried to load class " + className + " while constructing a JAXBContext. This class will be skipped. Processing Continues." );
+ log.debug(" The reason that class could not be loaded:" + e.toString());
+ }
+ e.printStackTrace();
+ }
+ }
+ }
+
}
Modified: webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/server/JAXWSMessageReceiver.java
URL: http://svn.apache.org/viewvc/webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/server/JAXWSMessageReceiver.java?view=diff&rev=476565&r1=476564&r2=476565
==============================================================================
--- webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/server/JAXWSMessageReceiver.java (original)
+++ webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/server/JAXWSMessageReceiver.java Sat Nov 18 08:58:26 2006
@@ -17,6 +17,8 @@
package org.apache.axis2.jaxws.server;
+import javax.xml.ws.WebServiceException;
+
import org.apache.axiom.soap.SOAPEnvelope;
import org.apache.axis2.AxisFault;
import org.apache.axis2.Constants.Configuration;
@@ -125,7 +127,13 @@
} catch (Exception e) {
ThreadContextMigratorUtil.performThreadCleanup(Constants.THREAD_CONTEXT_MIGRATOR_LIST_ID, axisRequestMsgCtx);
- throw ExceptionFactory.makeWebServiceException(e);
+
+ // Make a webservice exception (which will strip out a unnecessary stuff)
+ WebServiceException wse = ExceptionFactory.makeWebServiceException(e);
+
+ // The AxisEngine expects an AxisFault
+ throw AxisFault.makeFault(wse);
+
}
//This assumes that we are on the ultimate execution thread
Modified: webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/util/ClassUtils.java
URL: http://svn.apache.org/viewvc/webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/util/ClassUtils.java?view=diff&rev=476565&r1=476564&r2=476565
==============================================================================
--- webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/util/ClassUtils.java (original)
+++ webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/util/ClassUtils.java Sat Nov 18 08:58:26 2006
@@ -16,17 +16,9 @@
*/
package org.apache.axis2.jaxws.util;
-import java.io.File;
-import java.io.IOException;
-import java.io.UnsupportedEncodingException;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
-import java.net.URL;
-import java.net.URLDecoder;
-import java.util.ArrayList;
-import java.util.Enumeration;
import java.util.HashMap;
-import java.util.List;
import javax.jws.WebService;
import javax.xml.ws.Holder;
@@ -34,7 +26,6 @@
import javax.xml.ws.WebServiceClient;
import javax.xml.ws.WebServiceProvider;
-import org.apache.axis2.jaxws.i18n.Messages;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
@@ -229,86 +220,7 @@
return null;
}
- /**
- * This method will return all the Class names excluding the interfaces from a given package.
- * @param pkg Package
- * @return
- * @throws ClassNotFoundException
- */
- public static List<Class> getAllClassesFromPackage(Package pkg) throws ClassNotFoundException {
- if (pkg == null) {
- return new ArrayList<Class>();
- }
- // This will hold a list of directories matching the pckgname. There may be more than one if a package is split over multiple jars/paths
- String pckgname = pkg.getName();
- ArrayList<File> directories = new ArrayList<File>();
- try {
- ClassLoader cld = Thread.currentThread().getContextClassLoader();
- if (cld == null) {
- if(log.isDebugEnabled()){
- log.debug("Unable to get class loader");
- }
- throw new ClassNotFoundException(Messages.getMessage("ClassUtilsErr1"));
- }
- String path = pckgname.replace('.', '/');
- // Ask for all resources for the path
- Enumeration<URL> resources = cld.getResources(path);
- while (resources.hasMoreElements()) {
- directories.add(new File(URLDecoder.decode(resources.nextElement().getPath(), "UTF-8")));
- }
- } catch (UnsupportedEncodingException e) {
- if(log.isDebugEnabled()){
- log.debug(pckgname + " does not appear to be a valid package (Unsupported encoding)");
- }
- throw new ClassNotFoundException(Messages.getMessage("ClassUtilsErr2", pckgname));
- } catch (IOException e) {
- if(log.isDebugEnabled()){
- log.debug("IOException was thrown when trying to get all resources for "+ pckgname);
- }
- throw new ClassNotFoundException(Messages.getMessage("ClassUtilsErr3", pckgname));
- }
-
- ArrayList<Class> classes = new ArrayList<Class>();
- // For every directory identified capture all the .class files
- for (File directory : directories) {
- if (log.isDebugEnabled()) {
- log.debug("Adding classes from: " + directory.getName());
- }
- if (directory.exists()) {
- // Get the list of the files contained in the package
- String[] files = directory.list();
- for (String file : files) {
- // we are only interested in .class files
- if (file.endsWith(".class")) {
- // removes the .class extension
- // TODO Java2 Sec
- try {
- Class clazz = Class.forName(pckgname + '.' + file.substring(0, file.length() - 6),
- false,
- Thread.currentThread().getContextClassLoader());
- // Don't add any interfaces or JAXWS specific classes.
- // Only classes that represent data and can be marshalled
- // by JAXB should be added.
- if(!clazz.isInterface()
- && getDefaultPublicConstructor(clazz) != null
- && !isJAXWSClass(clazz)){
- if (log.isDebugEnabled()) {
- log.debug("Adding class: " + file);
- }
- classes.add(clazz);
- }
- } catch (Exception e) {
- e.printStackTrace();
- }
-
- }
- }
- }
- }
- return classes;
- }
-
- private static final Class[] noClass=new Class[] {};
+ private static final Class[] noClass=new Class[] {};
/**
* Get the default public constructor
* @param clazz
Modified: webservices/axis2/trunk/java/modules/jaxws/test/org/apache/axis2/jaxws/proxy/RPCProxyTests.java
URL: http://svn.apache.org/viewvc/webservices/axis2/trunk/java/modules/jaxws/test/org/apache/axis2/jaxws/proxy/RPCProxyTests.java?view=diff&rev=476565&r1=476564&r2=476565
==============================================================================
--- webservices/axis2/trunk/java/modules/jaxws/test/org/apache/axis2/jaxws/proxy/RPCProxyTests.java (original)
+++ webservices/axis2/trunk/java/modules/jaxws/test/org/apache/axis2/jaxws/proxy/RPCProxyTests.java Sat Nov 18 08:58:26 2006
@@ -24,8 +24,10 @@
import javax.xml.namespace.QName;
import javax.xml.ws.BindingProvider;
+import javax.xml.ws.Dispatch;
import javax.xml.ws.Service;
+import org.apache.axis2.jaxws.dispatch.DispatchTestConstants;
import org.apache.axis2.jaxws.proxy.rpclit.sei.RPCLit;
import junit.framework.TestCase;
@@ -56,6 +58,20 @@
}
/**
+ * Utility Method to get a Dispatch<String>
+ * @return
+ * @throws MalformedURLException
+ */
+ public Dispatch<String> getDispatch() throws MalformedURLException {
+ File wsdl= new File(wsdlLocation);
+ URL wsdlUrl = wsdl.toURL();
+ Service service = Service.create(null, serviceName);
+ service.addPort(portName, null, axisEndpoint);
+ Dispatch<String> dispatch = service.createDispatch(portName, String.class, Service.Mode.PAYLOAD);
+ return dispatch;
+ }
+
+ /**
* Simple test that ensures that we can echo a string to an rpc/lit web service
*/
public void testSimple() throws Exception {
@@ -64,7 +80,74 @@
String request = "This is a test...";
String response = proxy.testSimple(request);
- assert(response != null);
+ assertTrue(response != null);
+ assert(response.equals(request));
+ }catch(Exception e){
+ e.printStackTrace();
+ fail("Exception received" + e);
+ }
+ }
+
+ public void testSimple_Dispatch() throws Exception {
+ // Send a payload that simulates
+ // the rpc message
+ String request = "<tns:testSimple xmlns:tns='http://org/apache/axis2/jaxws/proxy/rpclit'>" +
+ "<tns:simpleIn xsi:type='xsd:string' xmlns:xsd='http://www.w3.org/2001/XMLSchema' xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'>" +
+ "PAYLOAD WITH XSI:TYPE" +
+ "</tns:simpleIn></tns:testSimple>";
+ Dispatch<String> dispatch = getDispatch();
+ String response = dispatch.invoke(request);
+
+ assertNotNull("dispatch invoke returned null", response);
+ System.out.println(response);
+
+ // Check to make sure the content is correct
+ assertTrue(!response.contains("soap"));
+ assertTrue(!response.contains("Envelope"));
+ assertTrue(!response.contains("Body"));
+ assertTrue(!response.contains("Fault"));
+ assertTrue(response.contains("simpleOut"));
+ assertTrue(response.contains("testSimpleResponse"));
+ assertTrue(response.contains("PAYLOAD WITH XSI:TYPE"));
+ }
+
+ public void _testSimple_DispatchWithoutXSIType() throws Exception {
+ // Send a payload that simulates
+ // the rpc message
+ String request = "<tns:testSimple xmlns:tns='http://org/apache/axis2/jaxws/proxy/rpclit'>" +
+ "<tns:simpleIn>" +
+ "PAYLOAD WITH XSI:TYPE" +
+ "</tns:simpleIn></tns:testSimple>";
+ Dispatch<String> dispatch = getDispatch();
+ String response = dispatch.invoke(request);
+
+
+ assertNotNull("dispatch invoke returned null", response);
+ System.out.println(response);
+
+ // Check to make sure the content is correct
+ assertTrue(!response.contains("soap"));
+ assertTrue(!response.contains("Envelope"));
+ assertTrue(!response.contains("Body"));
+ assertTrue(!response.contains("Fault"));
+ assertTrue(response.contains("simpleOut"));
+ assertTrue(response.contains("testSimpleResponse"));
+ assertTrue(response.contains("PAYLOAD WITH XSI:TYPE"));
+ }
+
+ /**
+ * Simple test that ensures that we can echo a string to an rpc/lit web service
+ */
+ public void testStringList() throws Exception {
+ try{
+ RPCLit proxy = getProxy();
+ String[] request = new String[] {"Hello" , "World"};
+
+ String[] response = proxy.testStringList2(request);
+ assertTrue(response != null);
+ assertTrue(response.length==2);
+ assertTrue(response[0].equals("Hello"));
+ assertTrue(response[1].equals("World"));
assert(response.equals(request));
}catch(Exception e){
e.printStackTrace();
---------------------------------------------------------------------
To unsubscribe, e-mail: axis-cvs-unsubscribe@ws.apache.org
For additional commands, e-mail: axis-cvs-help@ws.apache.org