1 /*
   2  * Copyright (c) 2020, 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 /**
  25  * @test
  26  * @bug 8244778
  27  * @summary Make sure that the ServicesCatalogs for boot/platform/app loaders are properly archived.
  28  * @requires vm.cds
  29  * @modules java.naming
  30  * @library /test/lib
  31  * @run driver ServiceLoaderTest
  32  */
  33 
  34 import java.util.ArrayList;
  35 import java.util.Collections;
  36 import java.util.Comparator;
  37 import java.util.Iterator;
  38 import java.util.ServiceLoader;
  39 import java.util.spi.ToolProvider;
  40 import javax.naming.spi.InitialContextFactory;
  41 import jdk.test.lib.cds.CDSTestUtils;
  42 import jdk.test.lib.cds.CDSOptions;
  43 import jdk.test.lib.process.OutputAnalyzer;
  44 
  45 public class ServiceLoaderTest {
  46     public static void main(String[] args) throws Exception {
  47         CDSOptions opts = new CDSOptions();
  48 
  49         CDSTestUtils.createArchiveAndCheck(opts);
  50 
  51         // Some mach5 tiers run with -vmoptions:-Xlog:cds=debug. This would cause the outputs to mismatch.
  52         // Force -Xlog:cds=warning to supress the CDS logs.
  53         opts.setUseVersion(false);
  54         opts.addSuffix("-showversion", "-Xlog:cds=warning", "ServiceLoaderApp");
  55         OutputAnalyzer out1 = CDSTestUtils.runWithArchive(opts);
  56 
  57         opts.setXShareMode("off");
  58         OutputAnalyzer out2 = CDSTestUtils.runWithArchive(opts);
  59 
  60         compare(out1, out2);
  61     }
  62 
  63     static void compare(OutputAnalyzer out1, OutputAnalyzer out2) {
  64         String[] arr1 = splitLines(out1);
  65         String[] arr2 = splitLines(out2);
  66 
  67         int max = arr1.length > arr2.length ? arr1.length : arr2.length;
  68         for (int i = 0; i < max; i++) {
  69             if (i >= arr1.length) {
  70                 mismatch(i, "<EOF>", arr2[i]);
  71             }
  72             if (i >= arr2.length) {
  73                 mismatch(i, arr1[i], "<EOF>");
  74             }
  75             if (!arr1[i].equals(arr2[i])) {
  76                 mismatch(i, arr1[i], arr2[i]);
  77             }
  78         }
  79     }
  80 
  81     static String[] splitLines(OutputAnalyzer out) {
  82         return out.getStdout().split("\n");
  83     }
  84 
  85     static void mismatch(int i, String s1, String s2) {
  86         System.out.println("Mismatched line: " + i);
  87         System.out.println("cds on : " + s1);
  88         System.out.println("cds off: " + s2);
  89         throw new RuntimeException("Mismatched line " + i + ": \"" + s1 + "\" vs \"" + s2 + "\"");
  90     }
  91 }
  92 
  93 class ServiceLoaderApp {
  94     public static void main(String args[]) throws Exception {
  95         doTest(ToolProvider.class);
  96         doTest(InitialContextFactory.class);
  97     }
  98 
  99     static void doTest(Class c) throws Exception {
 100         System.out.println("============================================================");
 101         System.out.println("Testing : " + c.getName());
 102         System.out.println("============================================================");
 103 
 104         dump("default",         ServiceLoader.load(c));
 105         dump("null loader",     ServiceLoader.load(c, null));
 106         dump("platform loader", ServiceLoader.load(c, ServiceLoaderApp.class.getClassLoader().getParent()));
 107         dump("system loader",   ServiceLoader.load(c, ServiceLoaderApp.class.getClassLoader()));
 108     }
 109 
 110     static void dump(String testCase, ServiceLoader loader) throws Exception {
 111         System.out.println("[TEST CASE] " + testCase);
 112         System.out.println("[svcloader] " + asString(loader));
 113         Iterator it = loader.iterator();
 114         ArrayList<String> list = new ArrayList<>();
 115         while (it.hasNext()) {
 116             list.add(asString(it.next().toString()));
 117         }
 118         Collections.sort(list);
 119         for (String s : list) {
 120             System.out.println(s);
 121         }
 122     }
 123 
 124     static String asString(Object o) {
 125         String s = o.toString();
 126         int n = s.indexOf("@");
 127         if (n >= 0) {
 128             s = s.substring(0, n);
 129         }
 130         return s;
 131     }
 132 }