You are viewing a plain text version of this content. The canonical link for it is here.
Posted to axis-cvs@ws.apache.org by sc...@apache.org on 2008/04/12 14:21:31 UTC
svn commit: r647440 - in
/webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/message/databinding:
JAXBUtils.java impl/ClassFinderImpl.java
Author: scheu
Date: Sat Apr 12 05:21:30 2008
New Revision: 647440
URL: http://svn.apache.org/viewvc?rev=647440&view=rev
Log:
AXIS2-3735
Contributor:Rich Scheuerle
Changes to JAXBUtils to only load classes from the input packages (not the nested packages).
If JAXBUtils uses the "newInstance(Class[])" approach, the classloader is switched to the input classloader.
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/message/databinding/impl/ClassFinderImpl.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?rev=647440&r1=647439&r2=647440&view=diff
==============================================================================
--- 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 Apr 12 05:21:30 2008
@@ -158,16 +158,16 @@
Map<String, JAXBContextValue> innerMap = null;
innerMap = getInnerMap(cacheKey, cl);
if (innerMap == null) {
- synchronized(jaxbMap) {
- innerMap = getInnerMap(cacheKey, cl);
- if(innerMap==null) {
- adjustPoolSize(jaxbMap);
- innerMap = new ConcurrentHashMap<String, JAXBContextValue>();
- if(cacheKey != null) {
+ synchronized(jaxbMap) {
+ innerMap = getInnerMap(cacheKey, cl);
+ if(innerMap==null) {
+ adjustPoolSize(jaxbMap);
+ innerMap = new ConcurrentHashMap<String, JAXBContextValue>();
+ if (cacheKey != null) {
jaxbMap.put(cacheKey, innerMap);
}
}
- }
+ }
}
if (contextPackages == null) {
@@ -176,19 +176,19 @@
JAXBContextValue contextValue = innerMap.get(key);
if (contextValue == null) {
- synchronized (innerMap) {
- contextValue = innerMap.get(key);
- if(contextValue==null) {
- adjustPoolSize(innerMap);
-
- // Create a copy of the contextPackages. This new TreeSet will
- // contain only the valid contextPackages.
- // Note: The original contextPackage set is accessed by multiple
- // threads and should not be altered.
-
- TreeSet<String> validContextPackages = new TreeSet<String>(contextPackages);
- contextValue = createJAXBContextValue(validContextPackages, cl);
-
+ synchronized (innerMap) {
+ contextValue = innerMap.get(key);
+ if(contextValue==null) {
+ adjustPoolSize(innerMap);
+
+ // Create a copy of the contextPackages. This new TreeSet will
+ // contain only the valid contextPackages.
+ // Note: The original contextPackage set is accessed by multiple
+ // threads and should not be altered.
+
+ TreeSet<String> validContextPackages = new TreeSet<String>(contextPackages);
+ contextValue = createJAXBContextValue(validContextPackages, cl);
+
// If we don't get all the classes, try the cached classloader
if (cacheKey != null && validContextPackages.size() != contextPackages.size()) {
validContextPackages = new TreeSet<String>(contextPackages);
@@ -196,15 +196,15 @@
}
// Put the new context in the map keyed by both the original and valid list of packages
- String validPackagesKey = validContextPackages.toString();
- innerMap.put(key, contextValue);
- innerMap.put(validPackagesKey, contextValue);
- if (log.isDebugEnabled()) {
- log.debug("JAXBContext [created] for " + key);
- log.debug("JAXBContext also stored by the list of valid packages:" + validPackagesKey);
- }
- }
- }
+ String validPackagesKey = validContextPackages.toString();
+ innerMap.put(key, contextValue);
+ innerMap.put(validPackagesKey, contextValue);
+ if (log.isDebugEnabled()) {
+ log.debug("JAXBContext [created] for " + key);
+ log.debug("JAXBContext also stored by the list of valid packages:" + validPackagesKey);
+ }
+ }
+ }
} else {
if (log.isDebugEnabled()) {
log.debug("JAXBContext [from pool] for " + key);
@@ -214,23 +214,23 @@
return contextValue.jaxbContext;
}
- private static Map<String, JAXBContextValue> getInnerMap(ClassLoader cacheKey, ClassLoader cl) {
- Map<String, JAXBContextValue> innerMap;
- if(cacheKey != null) {
+ private static Map<String, JAXBContextValue> getInnerMap(ClassLoader cacheKey, ClassLoader cl) {
+ Map<String, JAXBContextValue> innerMap;
+ if(cacheKey != null) {
if(log.isDebugEnabled()) {
log.debug("Using supplied classloader to retrieve JAXBContext: " +
- cacheKey);
+ cacheKey);
}
innerMap = jaxbMap.get(cacheKey);
}else {
if(log.isDebugEnabled()) {
log.debug("Using classloader from Thread to retrieve JAXBContext: " +
- cl);
+ cl);
}
innerMap = jaxbMap.get(cl);
}
- return innerMap;
- }
+ return innerMap;
+ }
/**
* Create a JAXBContext using the contextPackages
@@ -245,10 +245,13 @@
JAXBContextValue contextValue = null;
if (log.isDebugEnabled()) {
+
log.debug("Following packages are in this batch of getJAXBContext() :");
+
for (String pkg : contextPackages) {
log.debug(pkg);
}
+ log.debug("This classloader will be used to construct the JAXBContext" + cl);
}
// The contextPackages is a set of package names that are constructed using PackageSetBuilder.
// PackageSetBuilder gets the packages names from various sources.
@@ -381,7 +384,7 @@
//Lets add all common array classes
addCommonArrayClasses(fullList);
Class[] classArray = fullList.toArray(new Class[0]);
- JAXBContext context = JAXBContext_newInstance(classArray);
+ JAXBContext context = JAXBContext_newInstance(classArray, cl);
if (context != null) {
contextValue = new JAXBContextValue(context, CONSTRUCTION_TYPE.BY_CLASS_ARRAY);
}
@@ -635,7 +638,9 @@
try {
// This will load classes from directory
- classes.addAll(getClassesFromDirectory(pkg, cl));
+ List<Class> classesFromDir = getClassesFromDirectory(pkg, cl);
+ checkClasses(classesFromDir, pkg);
+ classes.addAll(classesFromDir);
} catch (ClassNotFoundException e) {
if (log.isDebugEnabled()) {
log.debug("getClassesFromDirectory failed to get Classes");
@@ -648,7 +653,11 @@
ClassFinderFactory cff =
(ClassFinderFactory)FactoryRegistry.getFactory(ClassFinderFactory.class);
ClassFinder cf = cff.getClassFinder();
- classes.addAll(cf.getClassesFromJarFile(pkg, cl));
+
+ List<Class> classesFromJar = cf.getClassesFromJarFile(pkg, cl);
+
+ checkClasses(classesFromJar, pkg);
+ classes.addAll(classesFromJar);
}
} catch (ClassNotFoundException e) {
if (log.isDebugEnabled()) {
@@ -658,6 +667,32 @@
return classes;
}
+
+ /**
+ * @param list
+ * @param pkg
+ */
+ private static void checkClasses(List<Class> list, String pkg) {
+ // The installed classfinder or directory search may inadvertently add too many
+ // classes. This rountine is a 'double check' to make sure that the classes
+ // are acceptable.
+ for (int i=0; i<list.size();) {
+ Class cls = list.get(i);
+ if (!cls.isInterface() &&
+ ClassUtils.getDefaultPublicConstructor(cls) != null &&
+ !ClassUtils.isJAXWSClass(cls) &&
+ cls.getPackage().getName().equals(pkg)) {
+ i++; // Acceptable class
+ } else {
+ if (log.isDebugEnabled()) {
+ log.debug("Removing class " + cls + " from consideration because it is not in package " + pkg +
+ " or is an interface or does not have a public constructor or is" +
+ " a jaxws class");
+ }
+ list.remove(i);
+ }
+ }
+ }
private static ArrayList<Class> getClassesFromDirectory(String pkg, ClassLoader cl)
throws ClassNotFoundException {
@@ -892,10 +927,12 @@
* Create JAXBContext from Class[]
*
* @param classArray
+ * @param cl ClassLoader that loaded the classes
* @return
* @throws Exception
*/
- private static JAXBContext JAXBContext_newInstance(final Class[] classArray)
+ private static JAXBContext JAXBContext_newInstance(final Class[] classArray,
+ final ClassLoader cl)
throws JAXBException {
// NOTE: This method must remain private because it uses AccessController
JAXBContext jaxbContext = null;
@@ -911,7 +948,17 @@
jaxbContext = (JAXBContext)AccessController.doPrivileged(
new PrivilegedExceptionAction() {
public Object run() throws JAXBException {
- return JAXBContext.newInstance(classArray);
+ // Unlike the JAXBContext.newInstance(Class[]) method
+ // does now accept a classloader. To workaround this
+ // issue, the classloader is temporarily changed to cl
+ Thread currentThread = Thread.currentThread();
+ ClassLoader savedClassLoader = currentThread.getContextClassLoader();
+ try {
+ currentThread.setContextClassLoader(cl);
+ return JAXBContext.newInstance(classArray);
+ } finally {
+ currentThread.setContextClassLoader(savedClassLoader);
+ }
}
}
);
Modified: webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/message/databinding/impl/ClassFinderImpl.java
URL: http://svn.apache.org/viewvc/webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/message/databinding/impl/ClassFinderImpl.java?rev=647440&r1=647439&r2=647440&view=diff
==============================================================================
--- webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/message/databinding/impl/ClassFinderImpl.java (original)
+++ webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/message/databinding/impl/ClassFinderImpl.java Sat Apr 12 05:21:30 2008
@@ -79,7 +79,8 @@
// 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()
+ if (!clazz.isInterface() &&
+ clazz.getPackage().getName().equals(pkg)
&& ClassUtils
.getDefaultPublicConstructor(clazz) != null
&& !ClassUtils.isJAXWSClass(clazz)) {
---------------------------------------------------------------------
To unsubscribe, e-mail: axis-cvs-unsubscribe@ws.apache.org
For additional commands, e-mail: axis-cvs-help@ws.apache.org