1 /*
   2  * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.
   8  *
   9  * This code is distributed in the hope that it will be useful, but WITHOUT
  10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  12  * version 2 for more details (a copy is included in the LICENSE file that
  13  * accompanied this code).
  14  *
  15  * You should have received a copy of the GNU General Public License version
  16  * 2 along with this work; if not, write to the Free Software Foundation,
  17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  18  *
  19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  */
  23 
  24 import static org.testng.Assert.assertEquals;
  25 import static org.testng.Assert.assertTrue;
  26 
  27 import java.io.File;
  28 import java.net.URL;
  29 import java.net.URLClassLoader;
  30 import java.nio.file.Files;
  31 import java.nio.file.Path;
  32 import java.nio.file.Paths;
  33 
  34 import jdk.test.lib.compiler.CompilerUtils;
  35 
  36 import org.testng.Assert;
  37 import org.testng.annotations.BeforeTest;
  38 import org.testng.annotations.Test;
  39 import org.xml.sax.XMLReader;
  40 import org.xml.sax.helpers.XMLReaderFactory;
  41 
  42 /*
  43  * @test
  44  * @library /test/lib
  45  * @run testng XMLReaderFactoryTest
  46  * @bug 8152912 8015099 8156119
  47  * @summary Tests XMLReaderFactory can work as ServiceLoader compliant, as well as backward compatible
  48  */
  49 
  50 @Test
  51 public class XMLReaderFactoryTest {
  52     private static final String TEST_SRC = System.getProperty("test.src");
  53 
  54     private static final Path SRC_DIR = Paths.get(TEST_SRC, "src").resolve("xmlprovider3");
  55     private static final Path CLASSES_DIR = Paths.get("classes");
  56     private static final Path LEGACY_DIR = CLASSES_DIR.resolve("legacy");
  57     private static final Path SERVICE_DIR = CLASSES_DIR.resolve("service");
  58 
  59     // resources to copy to the class path
  60     private static final String LEGACY_SERVICE_FILE = "legacy/META-INF/services/org.xml.sax.driver";
  61     private static final String SERVICE_FILE = "service/META-INF/services/org.xml.sax.XMLReader";
  62 
  63     /*
  64      * Compile class and copy service files
  65      */
  66     @BeforeTest
  67     public void setup() throws Exception {
  68         setup(LEGACY_DIR, LEGACY_SERVICE_FILE);
  69         setup(SERVICE_DIR, SERVICE_FILE);
  70     }
  71 
  72     private void setup(Path dest, String serviceFile) throws Exception {
  73         Files.createDirectories(dest);
  74         assertTrue(CompilerUtils.compile(SRC_DIR, dest));
  75 
  76         Path file = Paths.get(serviceFile.replace('/', File.separatorChar));
  77         Path source = SRC_DIR.resolve(file);
  78         Path target = CLASSES_DIR.resolve(file);
  79         Files.createDirectories(target.getParent());
  80         Files.copy(source, target);
  81 
  82     }
  83 
  84     public void testService() throws Exception {
  85         ClassLoader clBackup = Thread.currentThread().getContextClassLoader();
  86         try {
  87             URL[] classUrls = { SERVICE_DIR.toUri().toURL() };
  88             URLClassLoader loader = new URLClassLoader(classUrls, ClassLoader.getSystemClassLoader().getParent());
  89 
  90             // set TCCL and try locating the provider
  91             Thread.currentThread().setContextClassLoader(loader);
  92             XMLReader reader = XMLReaderFactory.createXMLReader();
  93             assertEquals(reader.getClass().getName(), "xp3.XMLReaderImpl");
  94         } finally {
  95             Thread.currentThread().setContextClassLoader(clBackup);
  96         }
  97     }
  98 
  99     public void testLegacy() throws Exception {
 100         ClassLoader clBackup = Thread.currentThread().getContextClassLoader();
 101         try {
 102             URL[] classUrls = { LEGACY_DIR.toUri().toURL() };
 103             URLClassLoader loader = new URLClassLoader(classUrls, ClassLoader.getSystemClassLoader().getParent());
 104 
 105             // set TCCL and try locating the provider
 106             Thread.currentThread().setContextClassLoader(loader);
 107             XMLReader reader1 = XMLReaderFactory.createXMLReader();
 108             assertEquals(reader1.getClass().getName(), "xp3.XMLReaderImpl");
 109 
 110             // now point to a random URL
 111             Thread.currentThread().setContextClassLoader(
 112                     new URLClassLoader(new URL[0], ClassLoader.getSystemClassLoader().getParent()));
 113             // ClassNotFoundException if also trying to load class of reader1, which
 114             // would be the case before 8152912
 115             XMLReader reader2 = XMLReaderFactory.createXMLReader();
 116             assertEquals(reader2.getClass().getName(), "com.sun.org.apache.xerces.internal.parsers.SAXParser");
 117         } finally {
 118             Thread.currentThread().setContextClassLoader(clBackup);
 119         }
 120     }
 121 }