Return-Path: X-Original-To: archive-asf-public-internal@cust-asf2.ponee.io Delivered-To: archive-asf-public-internal@cust-asf2.ponee.io Received: from cust-asf.ponee.io (cust-asf.ponee.io [163.172.22.183]) by cust-asf2.ponee.io (Postfix) with ESMTP id 4074D200CC6 for ; Mon, 12 Jun 2017 16:09:38 +0200 (CEST) Received: by cust-asf.ponee.io (Postfix) id 3F3CA160BD9; Mon, 12 Jun 2017 14:09:38 +0000 (UTC) Delivered-To: archive-asf-public@cust-asf.ponee.io Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by cust-asf.ponee.io (Postfix) with SMTP id 3ECB0160BED for ; Mon, 12 Jun 2017 16:09:37 +0200 (CEST) Received: (qmail 32297 invoked by uid 500); 12 Jun 2017 14:09:36 -0000 Mailing-List: contact commits-help@cxf.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@cxf.apache.org Delivered-To: mailing list commits@cxf.apache.org Received: (qmail 32234 invoked by uid 99); 12 Jun 2017 14:09:36 -0000 Received: from git1-us-west.apache.org (HELO git1-us-west.apache.org) (140.211.11.23) by apache.org (qpsmtpd/0.29) with ESMTP; Mon, 12 Jun 2017 14:09:36 +0000 Received: by git1-us-west.apache.org (ASF Mail Server at git1-us-west.apache.org, from userid 33) id 5B084E04F2; Mon, 12 Jun 2017 14:09:35 +0000 (UTC) Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit From: amccright@apache.org To: commits@cxf.apache.org Date: Mon, 12 Jun 2017 14:09:40 -0000 Message-Id: In-Reply-To: <23ac3dbf19b346968e86de05cc673415@git.apache.org> References: <23ac3dbf19b346968e86de05cc673415@git.apache.org> X-Mailer: ASF-Git Admin Mailer Subject: [6/7] cxf git commit: CXF-7349: Resolve NPE when TCCL is null archived-at: Mon, 12 Jun 2017 14:09:38 -0000 CXF-7349: Resolve NPE when TCCL is null Project: http://git-wip-us.apache.org/repos/asf/cxf/repo Commit: http://git-wip-us.apache.org/repos/asf/cxf/commit/7043ded4 Tree: http://git-wip-us.apache.org/repos/asf/cxf/tree/7043ded4 Diff: http://git-wip-us.apache.org/repos/asf/cxf/diff/7043ded4 Branch: refs/heads/master Commit: 7043ded41dc7484a9c47b38888a191ee70802c11 Parents: cb14bf9 Author: Andy McCright Authored: Thu Apr 27 16:09:55 2017 -0500 Committer: Andy McCright Committed: Thu Apr 27 16:09:55 2017 -0500 ---------------------------------------------------------------------- .../common/classloader/ClassLoaderUtils.java | 21 +++--- .../classloader/ClassLoaderUtilsTest.java | 79 ++++++++++++++++++++ 2 files changed, 89 insertions(+), 11 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/cxf/blob/7043ded4/core/src/main/java/org/apache/cxf/common/classloader/ClassLoaderUtils.java ---------------------------------------------------------------------- diff --git a/core/src/main/java/org/apache/cxf/common/classloader/ClassLoaderUtils.java b/core/src/main/java/org/apache/cxf/common/classloader/ClassLoaderUtils.java index df7d30e..ce39516 100644 --- a/core/src/main/java/org/apache/cxf/common/classloader/ClassLoaderUtils.java +++ b/core/src/main/java/org/apache/cxf/common/classloader/ClassLoaderUtils.java @@ -89,11 +89,10 @@ public final class ClassLoaderUtils { * @param callingClass The Class object of the calling object */ public static URL getResource(String resourceName, Class callingClass) { - URL url = Thread.currentThread().getContextClassLoader().getResource(resourceName); + URL url = getContextClassLoader().getResource(resourceName); if (url == null && resourceName.startsWith("/")) { //certain classloaders need it without the leading / - url = Thread.currentThread().getContextClassLoader() - .getResource(resourceName.substring(1)); + url = getContextClassLoader().getResource(resourceName.substring(1)); } ClassLoader cluClassloader = ClassLoaderUtils.class.getClassLoader(); @@ -151,16 +150,14 @@ public final class ClassLoaderUtils { }; try { - urls = Thread.currentThread().getContextClassLoader() - .getResources(resourceName); + urls = getContextClassLoader().getResources(resourceName); } catch (IOException e) { //ignore } if (!urls.hasMoreElements() && resourceName.startsWith("/")) { //certain classloaders need it without the leading / try { - urls = Thread.currentThread().getContextClassLoader() - .getResources(resourceName.substring(1)); + urls = getContextClassLoader().getResources(resourceName.substring(1)); } catch (IOException e) { // ignore } @@ -295,16 +292,18 @@ public final class ClassLoaderUtils { } } - private static ClassLoader getContextClassLoader() { + static ClassLoader getContextClassLoader() { final SecurityManager sm = System.getSecurityManager(); if (sm != null) { return AccessController.doPrivileged(new PrivilegedAction() { public ClassLoader run() { - return Thread.currentThread().getContextClassLoader(); + ClassLoader loader = Thread.currentThread().getContextClassLoader(); + return loader != null ? loader : ClassLoader.getSystemClassLoader(); } }); - } - return Thread.currentThread().getContextClassLoader(); + } + ClassLoader loader = Thread.currentThread().getContextClassLoader(); + return loader != null ? loader : ClassLoader.getSystemClassLoader(); } private static ClassLoader getClassLoader(final Class clazz) { http://git-wip-us.apache.org/repos/asf/cxf/blob/7043ded4/core/src/test/java/org/apache/cxf/common/classloader/ClassLoaderUtilsTest.java ---------------------------------------------------------------------- diff --git a/core/src/test/java/org/apache/cxf/common/classloader/ClassLoaderUtilsTest.java b/core/src/test/java/org/apache/cxf/common/classloader/ClassLoaderUtilsTest.java new file mode 100644 index 0000000..8e1fa18 --- /dev/null +++ b/core/src/test/java/org/apache/cxf/common/classloader/ClassLoaderUtilsTest.java @@ -0,0 +1,79 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.apache.cxf.common.classloader; + +import java.net.MalformedURLException; +import java.net.URL; +import java.net.URLClassLoader; + +import org.junit.Assert; +import org.junit.Test; + +public class ClassLoaderUtilsTest extends Assert { + + private static void setTCCL(ClassLoader loader) { + Thread.currentThread().setContextClassLoader(loader); + } + + /** + * This test confirms that the expected thread context classloader + * is returned from the getContextClassLoader method. + */ + @Test + public void getContextClassLoader() throws MalformedURLException { + final ClassLoader nullLoader = null; + final ClassLoader jvmAppLoader = ClassLoader.getSystemClassLoader(); + final ClassLoader jvmExtLoader = jvmAppLoader.getParent(); + final ClassLoader testClassLoader = ClassLoaderUtilsTest.class.getClassLoader(); + final ClassLoader clildLoader = new URLClassLoader(new URL[]{new URL("file:/.")}); + final ClassLoader previousTCCL = Thread.currentThread().getContextClassLoader(); + + try { + // TCCL = null + setTCCL(nullLoader); + assertEquals("TCCL == null; wrong loader returned; expected JVM App loader", + jvmAppLoader, ClassLoaderUtils.getContextClassLoader()); + + // TCCL = JVM App CL + setTCCL(jvmAppLoader); + assertEquals("TCCL == JVM App loader; wrong loader returned; expected JVM App loader", + jvmAppLoader, ClassLoaderUtils.getContextClassLoader()); + + // TCCL = JVM Ext CL + setTCCL(jvmExtLoader); + assertEquals("TCCL == JVM Ext loader; wrong loader returned; expected JVM Ext loader", + jvmExtLoader, ClassLoaderUtils.getContextClassLoader()); + + // TCCL = This test class loader (which is likely also the JVM App CL) + setTCCL(testClassLoader); + assertEquals("TCCL == this test laoder; wrong loader returned; expected JVM App loader", + testClassLoader, ClassLoaderUtils.getContextClassLoader()); + + // TCCL = a random child classloader + setTCCL(clildLoader); + assertEquals("TCCL == random child loader, wrong loader returned; expected child of test class loader", + clildLoader, ClassLoaderUtils.getContextClassLoader()); + + } finally { + // reset the TCCL for other tests + setTCCL(previousTCCL); + } + } +}