# HG changeset patch # User dfuchs # Date 1466780597 -3600 # Node ID ab6a58b6301d3f07b14dc7125f3e494970f90b3a # Parent 34455cc82f5e5fd796c5eee77f08844543ef41d1 8150173: JAXBContext.newInstance causes PrivilegedActionException when createContext's declared in abstract class extended by discovered JAXB implementation Summary: trivial fix - the concrete class must be instantiated, not the class that defines the createContext method. Reviewed-by: lancea, mchung diff -r 34455cc82f5e -r ab6a58b6301d jdk/test/javax/xml/bind/JAXBContext/JAXBContextWithAbstractFactory.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/javax/xml/bind/JAXBContext/JAXBContextWithAbstractFactory.java Fri Jun 24 16:03:17 2016 +0100 @@ -0,0 +1,100 @@ +/* + * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +import java.security.Permission; +import java.security.Policy; +import java.security.ProtectionDomain; +import java.util.Map; +import javax.xml.bind.JAXBContext; +import javax.xml.bind.JAXBContextFactory; +import javax.xml.bind.JAXBException; + +/** + * @test + * @bug 8150173 + * @summary Verifies that a factory which inherit its createContext method + * from an abstract subclass of JAXBContextFactory can be instantiated. + * @compile -addmods java.xml.bind JAXBContextWithAbstractFactory.java + * @run main/othervm -addmods java.xml.bind JAXBContextWithAbstractFactory + */ +public class JAXBContextWithAbstractFactory { + private static JAXBContext tmp; + + public static abstract class FactoryBase implements JAXBContextFactory { + @Override + public JAXBContext createContext(Class[] classesToBeBound, + Map properties) throws JAXBException { + return tmp; + } + + @Override + public JAXBContext createContext(String contextPath, + ClassLoader classLoader, Map properties) + throws JAXBException { + return tmp; + } + } + + public static class Factory extends FactoryBase {} + + // test both without and then with a security manager as the code path + // can be different when System.getSecurityManager() != null; + public static void main(String[] args) throws JAXBException { + System.out.println("\nWithout security manager\n"); + test(); + + System.out.println("\nWith security manager\n"); + Policy.setPolicy(new Policy() { + @Override + public boolean implies(ProtectionDomain domain, Permission permission) { + return true; // allow all + } + }); + System.setSecurityManager(new SecurityManager()); + test(); + } + + public static void test() throws JAXBException { + System.clearProperty(JAXBContext.JAXB_CONTEXT_FACTORY); + System.out.println(JAXBContext.JAXB_CONTEXT_FACTORY + " = " + + System.getProperty(JAXBContext.JAXB_CONTEXT_FACTORY, "")); + System.out.println("Calling " + + "JAXBContext.newInstance(JAXBContextWithAbstractFactory.class)"); + tmp = JAXBContext.newInstance(JAXBContextWithAbstractFactory.class); + System.setProperty(JAXBContext.JAXB_CONTEXT_FACTORY, + "JAXBContextWithAbstractFactory$Factory"); + System.out.println(JAXBContext.JAXB_CONTEXT_FACTORY + " = " + + System.getProperty(JAXBContext.JAXB_CONTEXT_FACTORY)); + System.out.println("Calling " + + "JAXBContext.newInstance(JAXBContextWithAbstractFactory.class)"); + JAXBContext ctxt = JAXBContext.newInstance(JAXBContextWithAbstractFactory.class); + System.out.println("Successfully loaded JAXBcontext: " + + System.identityHashCode(ctxt) + "@" + ctxt.getClass().getName()); + if (ctxt != tmp) { + throw new RuntimeException("Wrong JAXBContext instance" + + "\n\texpected: " + + System.identityHashCode(tmp) + "@" + tmp.getClass().getName() + + "\n\tactual: " + + System.identityHashCode(ctxt) + "@" + ctxt.getClass().getName()); + } + } +} diff -r 34455cc82f5e -r ab6a58b6301d jdk/test/javax/xml/bind/JAXBContext/JAXBContextWithLegacyFactory.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/javax/xml/bind/JAXBContext/JAXBContextWithLegacyFactory.java Fri Jun 24 16:03:17 2016 +0100 @@ -0,0 +1,147 @@ +/* + * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +import java.security.Permission; +import java.security.Policy; +import java.security.ProtectionDomain; +import java.util.Map; +import javax.xml.bind.JAXBContext; +import javax.xml.bind.JAXBException; +import javax.xml.bind.Marshaller; +import javax.xml.bind.Unmarshaller; +import javax.xml.bind.Validator; + +/** + * @test + * @bug 8150173 + * @summary Verifies that a JAXBContext can be created with a legacy + * factory class that has static createContext methods. + * @compile -addmods java.xml.bind JAXBContextWithLegacyFactory.java + * @run main/othervm -addmods java.xml.bind JAXBContextWithLegacyFactory + */ +public class JAXBContextWithLegacyFactory { + private static JAXBContext tmp; + + public static class JAXBContextImpl extends JAXBContext { + public final Class creator; + JAXBContextImpl(Class creator) { + this.creator = creator; + } + + @Override + public Unmarshaller createUnmarshaller() throws JAXBException { + return tmp.createUnmarshaller(); + } + + @Override + public Marshaller createMarshaller() throws JAXBException { + return tmp.createMarshaller(); + } + + @Override + public Validator createValidator() throws JAXBException { + return tmp.createValidator(); + } + } + + public static abstract class FactoryBase { + public static JAXBContext createContext(Class[] classesToBeBound, + Map properties) throws JAXBException { + return new JAXBContextImpl(FactoryBase.class); + } + + public static JAXBContext createContext(String contextPath, + ClassLoader classLoader, Map properties) + throws JAXBException { + return new JAXBContextImpl(FactoryBase.class); + } + } + + public static class Factory1 extends FactoryBase {} + + public static class Factory2 extends FactoryBase { + public static JAXBContext createContext(Class[] classesToBeBound, + Map properties) throws JAXBException { + return new JAXBContextImpl(Factory2.class); + } + + public static JAXBContext createContext(String contextPath, + ClassLoader classLoader, Map properties) + throws JAXBException { + return new JAXBContextImpl(Factory2.class); + } + } + + // test both without and then with a security manager as the code path + // can be different when System.getSecurityManager() != null; + public static void main(String[] args) throws JAXBException { + System.out.println("\nWithout security manager\n"); + test(FactoryBase.class, FactoryBase.class); + test(Factory1.class, FactoryBase.class); + test(Factory2.class, Factory2.class); + + System.out.println("\nWith security manager\n"); + Policy.setPolicy(new Policy() { + @Override + public boolean implies(ProtectionDomain domain, Permission permission) { + return true; // allow all + } + }); + System.setSecurityManager(new SecurityManager()); + test(FactoryBase.class, FactoryBase.class); + test(Factory1.class, FactoryBase.class); + test(Factory2.class, Factory2.class); + } + + public static void test(Class factoryClass, Class creatorClass) throws JAXBException { + System.clearProperty(JAXBContext.JAXB_CONTEXT_FACTORY); + System.out.println("** Testing with Factory Class: " + factoryClass.getName()); + System.out.println(JAXBContext.JAXB_CONTEXT_FACTORY + " = " + + System.getProperty(JAXBContext.JAXB_CONTEXT_FACTORY, "")); + System.out.println("Calling " + + "JAXBContext.newInstance(JAXBContextWithLegacyFactory.class)"); + tmp = JAXBContext.newInstance(JAXBContextWithLegacyFactory.class); + System.setProperty(JAXBContext.JAXB_CONTEXT_FACTORY, + factoryClass.getName()); + System.out.println(JAXBContext.JAXB_CONTEXT_FACTORY + " = " + + System.getProperty(JAXBContext.JAXB_CONTEXT_FACTORY)); + System.out.println("Calling " + + "JAXBContext.newInstance(JAXBContextWithLegacyFactory.class)"); + JAXBContext ctxt = JAXBContext.newInstance(JAXBContextWithLegacyFactory.class); + System.out.println("Successfully loaded JAXBcontext: " + + System.identityHashCode(ctxt) + "@" + ctxt.getClass().getName()); + if (ctxt.getClass() != JAXBContextImpl.class) { + throw new RuntimeException("Wrong JAXBContext class" + + "\n\texpected: " + + System.identityHashCode(tmp) + "@" + JAXBContextImpl.class.getName() + + "\n\tactual: " + + System.identityHashCode(ctxt) + "@" + ctxt.getClass().getName()); + } + if (((JAXBContextImpl)ctxt).creator != creatorClass) { + throw new RuntimeException("Wrong Factory class" + + "\n\texpected: " + + System.identityHashCode(tmp) + "@" + creatorClass.getName() + + "\n\tactual: " + + System.identityHashCode(ctxt) + "@" + ((JAXBContextImpl)ctxt).creator.getName()); + } + } +} diff -r 34455cc82f5e -r ab6a58b6301d jdk/test/javax/xml/bind/JAXBContext/JAXBContextWithSubclassedFactory.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/javax/xml/bind/JAXBContext/JAXBContextWithSubclassedFactory.java Fri Jun 24 16:03:17 2016 +0100 @@ -0,0 +1,153 @@ +/* + * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +import java.security.Permission; +import java.security.Policy; +import java.security.ProtectionDomain; +import java.util.Map; +import javax.xml.bind.JAXBContext; +import javax.xml.bind.JAXBContextFactory; +import javax.xml.bind.JAXBException; +import javax.xml.bind.Marshaller; +import javax.xml.bind.Unmarshaller; +import javax.xml.bind.Validator; + +/** + * @test + * @bug 8150173 + * @summary Verifies that a factory which inherit its createContext method + * from a concrete subclass of JAXBContextFactory is be instantiated. + * @compile -addmods java.xml.bind JAXBContextWithSubclassedFactory.java + * @run main/othervm -addmods java.xml.bind JAXBContextWithSubclassedFactory + */ +public class JAXBContextWithSubclassedFactory { + static JAXBContext tmp; + + public static class JAXBContextImpl extends JAXBContext { + public final Class creator; + JAXBContextImpl(Class creator) { + this.creator = creator; + } + + @Override + public Unmarshaller createUnmarshaller() throws JAXBException { + return tmp.createUnmarshaller(); + } + + @Override + public Marshaller createMarshaller() throws JAXBException { + return tmp.createMarshaller(); + } + + @Override + public Validator createValidator() throws JAXBException { + return tmp.createValidator(); + } + } + + public static class FactoryBase implements JAXBContextFactory { + + @Override + public JAXBContext createContext(Class[] classesToBeBound, + Map properties) throws JAXBException { + return new JAXBContextImpl(this.getClass()); + } + + @Override + public JAXBContext createContext(String contextPath, + ClassLoader classLoader, Map properties) + throws JAXBException { + return new JAXBContextImpl(this.getClass()); + } + } + + public static class NonFactoryBase { + + public JAXBContext createContext(Class[] classesToBeBound, + Map properties) throws JAXBException { + return new JAXBContextImpl(this.getClass()); + } + + public JAXBContext createContext(String contextPath, + ClassLoader classLoader, Map properties) + throws JAXBException { + return new JAXBContextImpl(this.getClass()); + } + } + + public static class Factory1 extends FactoryBase {} + public static class Factory2 extends NonFactoryBase implements JAXBContextFactory {} + + // test both without and then with a security manager as the code path + // can be different when System.getSecurityManager() != null; + public static void main(String[] args) throws JAXBException { + System.out.println("\nWithout security manager\n"); + test(FactoryBase.class); + test(Factory1.class); + test(Factory2.class); + + System.out.println("\nWith security manager\n"); + Policy.setPolicy(new Policy() { + @Override + public boolean implies(ProtectionDomain domain, Permission permission) { + return true; // allow all + } + }); + System.setSecurityManager(new SecurityManager()); + test(FactoryBase.class); + test(Factory1.class); + test(Factory2.class); + } + + public static void test(Class factoryClass) throws JAXBException { + System.clearProperty(JAXBContext.JAXB_CONTEXT_FACTORY); + System.out.println("** Testing with Factory Class: " + factoryClass.getName()); + System.out.println(JAXBContext.JAXB_CONTEXT_FACTORY + " = " + + System.getProperty(JAXBContext.JAXB_CONTEXT_FACTORY, "")); + System.out.println("Calling " + + "JAXBContext.newInstance(JAXBContextWithSubclassedFactory.class)"); + tmp = JAXBContext.newInstance(JAXBContextWithSubclassedFactory.class); + System.setProperty(JAXBContext.JAXB_CONTEXT_FACTORY, + factoryClass.getName()); + System.out.println(JAXBContext.JAXB_CONTEXT_FACTORY + " = " + + System.getProperty(JAXBContext.JAXB_CONTEXT_FACTORY)); + System.out.println("Calling " + + "JAXBContext.newInstance(JAXBContextWithSubclassedFactory.class)"); + JAXBContext ctxt = JAXBContext.newInstance(JAXBContextWithSubclassedFactory.class); + System.out.println("Successfully loaded JAXBcontext: " + + System.identityHashCode(ctxt) + "@" + ctxt.getClass().getName()); + if (ctxt.getClass() != JAXBContextImpl.class) { + throw new RuntimeException("Wrong JAXBContext class" + + "\n\texpected: " + + System.identityHashCode(tmp) + "@" + JAXBContextImpl.class.getName() + + "\n\tactual: " + + System.identityHashCode(ctxt) + "@" + ctxt.getClass().getName()); + } + if (((JAXBContextImpl)ctxt).creator != factoryClass) { + throw new RuntimeException("Wrong Factory class" + + "\n\texpected: " + + System.identityHashCode(tmp) + "@" + factoryClass.getName() + + "\n\tactual: " + + System.identityHashCode(ctxt) + "@" + ((JAXBContextImpl)ctxt).creator.getName()); + } + } +}