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
24import static org.testng.Assert.assertSame;
25import static org.testng.Assert.assertTrue;
26
27import java.lang.ClassLoader;
28import java.lang.String;
29import java.lang.System;
30import java.lang.module.Configuration;
31import java.lang.module.ModuleFinder;
32import java.lang.reflect.Method;
33import java.nio.file.Paths;
34import java.nio.file.Path;
35import java.util.Collections;
36import java.util.Iterator;
37import java.util.ServiceLoader;
38import java.util.Set;
39
40import org.testng.annotations.BeforeTest;
41import org.testng.annotations.Test;
42
43import jdk.test.lib.compiler.CompilerUtils;
44
45/*
46 * @test
47 * @library /test/lib
48 * @run testng LayerModularXMLParserTest
49 * @bug 8078820 8156119
50 * @summary Tests JAXP lib works with layer and TCCL
51 */
52
53@Test
54public class LayerModularXMLParserTest {
55
56    private static final String TEST_SRC = System.getProperty("test.src");
57
58    private static final Path SRC_DIR = Paths.get(TEST_SRC, "src");
59    private static final Path MOD_DIR1 = Paths.get("mod1");
60    private static final Path MOD_DIR2 = Paths.get("mod2");
61
62    /*
63     * services provided by provider1
64     */
65    private static final String[] services1 = { "javax.xml.parsers.DocumentBuilderFactory",
66            "javax.xml.parsers.SAXParserFactory", "javax.xml.stream.XMLInputFactory",
67            "javax.xml.stream.XMLOutputFactory", "javax.xml.transform.TransformerFactory",
68            "javax.xml.validation.SchemaFactory", "javax.xml.xpath.XPathFactory" };
69
70    /*
71     * services provided by provider2
72     */
73    private static final String[] services2 = { "javax.xml.datatype.DatatypeFactory",
74            "javax.xml.stream.XMLEventFactory", "org.xml.sax.XMLReader" };
75
76    /*
77     * Compiles all modules used by the test
78     */
79    @BeforeTest
80    public void compileAll() throws Exception {
81        assertTrue(CompilerUtils.compile(SRC_DIR.resolve("xmlprovider1"), MOD_DIR1.resolve("xmlprovider1")));
82        assertTrue(CompilerUtils.compile(SRC_DIR.resolve("xmlprovider2"), MOD_DIR2.resolve("xmlprovider2")));
83        assertTrue(CompilerUtils.compile(SRC_DIR.resolve("test"), MOD_DIR1.resolve("test")));
84        assertTrue(CompilerUtils.compile(SRC_DIR.resolve("test"), MOD_DIR2.resolve("test")));
85    }
86
87    /*
88     * layer 1 is created on top of boot layer, layer1 includes module provider1.
89     *
90     * Instantiate each XML service, verify the services provided by provider1
91     * are loaded from layer 1, the other services are loaded from boot layer
92     */
93    public void testOneLayer() throws Exception {
94        ModuleFinder finder1 = ModuleFinder.of(MOD_DIR1);
95        Configuration cf1 = ModuleLayer.boot().configuration()
96                .resolveAndBind(finder1, ModuleFinder.of(), Set.of("test"));
97        ClassLoader scl = ClassLoader.getSystemClassLoader();
98        ModuleLayer layer1 = ModuleLayer.boot().defineModulesWithManyLoaders(cf1, scl);
99        ClassLoader cl1 = layer1.findLoader("test");
100
101        Method m = cl1.loadClass("test.XMLFactoryHelper").getMethod("instantiateXMLService", String.class);
102        for (String service : services1) {
103            Object o = m.invoke(null, service);
104            ModuleLayer providerLayer = o.getClass().getModule().getLayer();
105            assertSame(providerLayer, layer1);
106        }
107
108        for (String service : services2) {
109            Object o = m.invoke(null, service);
110            ModuleLayer providerLayer = o.getClass().getModule().getLayer();
111            assertSame(providerLayer, ModuleLayer.boot());
112        }
113
114    }
115
116    /*
117     * layer 1 is created on top of boot layer, layer 1 includes module provider1.
118     * layer 2 is created on top of layer 1, layer 2 includes module provider2.
119     *
120     * Instantiate each XML service, verify the services provided by provider1
121     * are loaded from layer 1, the services provided by provider2 are loaded from layer 2
122     */
123    public void testTwoLayer() throws Exception {
124        ModuleFinder finder1 = ModuleFinder.of(MOD_DIR1);
125        Configuration cf1 = ModuleLayer.boot().configuration()
126                .resolveAndBind(finder1, ModuleFinder.of(), Set.of("test"));
127        ClassLoader scl = ClassLoader.getSystemClassLoader();
128        ModuleLayer layer1 = ModuleLayer.boot().defineModulesWithManyLoaders(cf1, scl);
129
130        ModuleFinder finder2 = ModuleFinder.of(MOD_DIR2);
131        Configuration cf2 = cf1.resolveAndBind(finder2, ModuleFinder.of(), Set.of("test"));
132        ModuleLayer layer2 = layer1.defineModulesWithOneLoader(cf2, layer1.findLoader("test"));
133        ClassLoader cl2 = layer2.findLoader("test");
134
135        Method m = cl2.loadClass("test.XMLFactoryHelper").getMethod("instantiateXMLService", String.class);
136        for (String service : services1) {
137            Object o = m.invoke(null, service);
138            ModuleLayer providerLayer = o.getClass().getModule().getLayer();
139            assertSame(providerLayer, layer1);
140        }
141
142        for (String service : services2) {
143            Object o = m.invoke(null, service);
144            ModuleLayer providerLayer = o.getClass().getModule().getLayer();
145            assertSame(providerLayer, layer2);
146        }
147
148    }
149
150    /*
151     * layer 1 is created on top of boot layer, layer 1 includes module provider1 and provider2.
152     * layer 2 is created on top of layer 1, layer 2 includes module provider2.
153     *
154     * Instantiate each XML service, verify the services provided by provider1
155     * are loaded from layer 1, the services provided by provider2 are loaded from layer 2
156     */
157    public void testTwoLayerWithDuplicate() throws Exception {
158        ModuleFinder finder1 = ModuleFinder.of(MOD_DIR1, MOD_DIR2);
159        Configuration cf1 = ModuleLayer.boot().configuration()
160                .resolveAndBind(finder1, ModuleFinder.of(), Set.of("test"));
161        ClassLoader scl = ClassLoader.getSystemClassLoader();
162        ModuleLayer layer1 = ModuleLayer.boot().defineModulesWithManyLoaders(cf1, scl);
163
164        ModuleFinder finder2 = ModuleFinder.of(MOD_DIR2);
165        Configuration cf2 = cf1.resolveAndBind(finder2, ModuleFinder.of(), Set.of("test"));
166        ModuleLayer layer2 = layer1.defineModulesWithOneLoader(cf2, layer1.findLoader("test"));
167        ClassLoader cl2 = layer2.findLoader("test");
168
169        Method m = cl2.loadClass("test.XMLFactoryHelper").getMethod("instantiateXMLService", String.class);
170        for (String service : services1) {
171            Object o = m.invoke(null, service);
172            ModuleLayer providerLayer = o.getClass().getModule().getLayer();
173            assertSame(providerLayer, layer1);
174        }
175
176        for (String service : services2) {
177            Object o = m.invoke(null, service);
178            ModuleLayer providerLayer = o.getClass().getModule().getLayer();
179            assertSame(providerLayer, layer2);
180        }
181
182    }
183}
184