[LOG4J2-1320] Custom plugins are not loaded, URL protocol vfs is not supported. Create a JUnit Rule to manage the URLStreamHandlerFactory.
Project: http://git-wip-us.apache.org/repos/asf/logging-log4j2/repo Commit: http://git-wip-us.apache.org/repos/asf/logging-log4j2/commit/4157ef83 Tree: http://git-wip-us.apache.org/repos/asf/logging-log4j2/tree/4157ef83 Diff: http://git-wip-us.apache.org/repos/asf/logging-log4j2/diff/4157ef83 Branch: refs/heads/LOG4J2-1528 Commit: 4157ef83fa64899a1fcccc528456b03520261dde Parents: 73323cd Author: Gary Gregory <ggreg...@apache.org> Authored: Thu Aug 25 13:15:45 2016 -0700 Committer: Gary Gregory <ggreg...@apache.org> Committed: Thu Aug 25 13:15:45 2016 -0700 ---------------------------------------------------------------------- .../util/ResolverUtilCustomProtocolTest.java | 41 +++------ .../junit/URLStreamHandlerFactoryRule.java | 96 ++++++++++++++++++++ 2 files changed, 107 insertions(+), 30 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/4157ef83/log4j-core/src/test/java/org/apache/logging/log4j/core/config/plugins/util/ResolverUtilCustomProtocolTest.java ---------------------------------------------------------------------- diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/config/plugins/util/ResolverUtilCustomProtocolTest.java b/log4j-core/src/test/java/org/apache/logging/log4j/core/config/plugins/util/ResolverUtilCustomProtocolTest.java index 86bc000..532b9ef 100644 --- a/log4j-core/src/test/java/org/apache/logging/log4j/core/config/plugins/util/ResolverUtilCustomProtocolTest.java +++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/config/plugins/util/ResolverUtilCustomProtocolTest.java @@ -17,14 +17,9 @@ package org.apache.logging.log4j.core.config.plugins.util; -import static org.junit.Assert.assertEquals; import static org.apache.logging.log4j.core.config.plugins.util.ResolverUtilTest.compileAndCreateClassLoader; import static org.apache.logging.log4j.core.config.plugins.util.ResolverUtilTest.compileJarAndCreateClassLoader; - -import org.apache.logging.log4j.core.config.plugins.util.PluginRegistry.PluginTest; -import org.junit.AfterClass; -import org.junit.BeforeClass; -import org.junit.Test; +import static org.junit.Assert.assertEquals; import java.io.IOException; import java.lang.reflect.Field; @@ -38,12 +33,22 @@ import java.util.Collections; import java.util.Enumeration; import java.util.Hashtable; +import org.apache.logging.log4j.core.config.plugins.util.PluginRegistry.PluginTest; +import org.apache.logging.log4j.junit.URLStreamHandlerFactoryRule; +import org.junit.AfterClass; +import org.junit.Rule; +import org.junit.Test; + /** * Tests the ResolverUtil class for custom protocol like bundleresource, vfs, vfszip. */ public class ResolverUtilCustomProtocolTest { + @Rule + public URLStreamHandlerFactoryRule rule = new URLStreamHandlerFactoryRule(new NoopURLStreamHandlerFactory()); + static class NoopURLStreamHandlerFactory implements URLStreamHandlerFactory { + @Override public URLStreamHandler createURLStreamHandler(String protocol) { return new URLStreamHandler() { @@ -107,30 +112,6 @@ public class ResolverUtilCustomProtocolTest { } } - @BeforeClass - public static void defineURLHandler() { - URL.setURLStreamHandlerFactory(new NoopURLStreamHandlerFactory()); - } - - @AfterClass - public static void removeURLHandler() throws Exception { - // Simulate this - Not the best way, but no other choice welcome ? - // URL.setURLStreamHandlerFactory(null); - Field handlersFields = URL.class.getDeclaredField("handlers"); - if (!handlersFields.isAccessible()) { - handlersFields.setAccessible(true); - } - Field factoryFields = URL.class.getDeclaredField("factory"); - if (!factoryFields.isAccessible()) { - factoryFields.setAccessible(true); - } - - @SuppressWarnings("unchecked") - Hashtable<String, URLStreamHandler> handlers = (Hashtable<String, URLStreamHandler>) handlersFields.get(null); - handlers.clear(); - factoryFields.set(null, null); - } - @Test public void testExtractPathFromVfsEarJarWindowsUrl() throws Exception { final URL url = new URL( http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/4157ef83/log4j-core/src/test/java/org/apache/logging/log4j/junit/URLStreamHandlerFactoryRule.java ---------------------------------------------------------------------- diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/junit/URLStreamHandlerFactoryRule.java b/log4j-core/src/test/java/org/apache/logging/log4j/junit/URLStreamHandlerFactoryRule.java new file mode 100644 index 0000000..ac08bb3 --- /dev/null +++ b/log4j-core/src/test/java/org/apache/logging/log4j/junit/URLStreamHandlerFactoryRule.java @@ -0,0 +1,96 @@ +/* + * 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.logging.log4j.junit; + +import java.lang.reflect.Field; +import java.net.URL; +import java.net.URLStreamHandler; +import java.net.URLStreamHandlerFactory; +import java.util.Hashtable; + +import org.junit.Assert; +import org.junit.rules.TestRule; +import org.junit.runner.Description; +import org.junit.runners.model.Statement; + +/** + * Installs and restores the URL URLStreamHandlerFactory before and after tests. + * <p> + * Might need tweaking for different JREs. + * </p> + */ +public class URLStreamHandlerFactoryRule implements TestRule { + + public URLStreamHandlerFactoryRule() { + this(null); + } + + public URLStreamHandlerFactoryRule(URLStreamHandlerFactory newURLStreamHandlerFactory) { + this.newURLStreamHandlerFactory = newURLStreamHandlerFactory; + } + + private final URLStreamHandlerFactory newURLStreamHandlerFactory; + + void clearURLHandlers() throws Exception { + Field handlersFields = URL.class.getDeclaredField("handlers"); + if (handlersFields != null) { + if (!handlersFields.isAccessible()) { + handlersFields.setAccessible(true); + } + @SuppressWarnings("unchecked") + Hashtable<String, URLStreamHandler> handlers = (Hashtable<String, URLStreamHandler>) handlersFields + .get(null); + if (handlers != null) { + handlers.clear(); + } + } + } + + @Override + public Statement apply(final Statement base, final Description description) { + return new Statement() { + @Override + public void evaluate() throws Throwable { + Field factoryField = null; + int matches = 0; + URLStreamHandlerFactory oldFactory = null; + for (Field field : URL.class.getDeclaredFields()) { + if (URLStreamHandlerFactory.class.equals(field.getType())) { + factoryField = field; + matches++; + factoryField.setAccessible(true); + oldFactory = (URLStreamHandlerFactory) factoryField.get(null); + break; + } + } + Assert.assertNotNull("java.net URL does not declare a java.net.URLStreamHandlerFactory field", + factoryField); + Assert.assertEquals("java.net.URL declares multiple java.net.URLStreamHandlerFactory fields.", 1, + matches); + URL.setURLStreamHandlerFactory(newURLStreamHandlerFactory); + try { + base.evaluate(); + } finally { + clearURLHandlers(); + factoryField.set(null, null); + URL.setURLStreamHandlerFactory(oldFactory); + } + } + }; + } +}