1 /*
   2  * Copyright (c) 2007, 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 /*
  25  * @test
  26  * @bug 6627362
  27  * @summary javac generates code that uses array.clone,
  28  *          which is not available on JavaCard
  29  * @modules jdk.compiler
  30  *          jdk.jdeps/com.sun.tools.javap
  31  */
  32 
  33 import java.io.*;
  34 import java.lang.reflect.*;
  35 import java.net.*;
  36 import java.util.*;
  37 
  38 public class T6627362 {
  39     static String testSrc = System.getProperty("test.src", ".");
  40 
  41     public static void main(String... args) throws Exception {
  42         new T6627362().run();
  43     }
  44 
  45     public void run() throws Exception {
  46         testStandard();
  47         testNoClone();
  48         if (errors > 0)
  49             throw new Error(errors + " test cases failed");
  50     }
  51 
  52     void testStandard() throws Exception {
  53         // compile and disassemble E.java, check for reference to Object.clone()
  54         File x = new File(testSrc, "x");
  55         String[] jcArgs = { "-d", ".",
  56                             new File(x, "E.java").getPath() };
  57         compile(jcArgs);
  58 
  59         String[] jpArgs = { "-classpath", ".", "-c", "E" };
  60 
  61         StringWriter sw = new StringWriter();
  62         javap(new PrintWriter(sw, true), jpArgs);
  63         check(sw.toString(), "Method \"[LE;\".clone:()Ljava/lang/Object;");
  64         callValues();
  65     }
  66 
  67     void testNoClone() throws Exception {
  68         // compile and disassemble E.java, using modified Object.java,
  69         // check for reference to System.arraycopy
  70         File x = new File(testSrc, "x");
  71         String[] jcArgs = { "-d", ".", "--patch-module", "java.base=" + x.getAbsolutePath(),
  72                             new File(x, "E.java").getPath(),
  73                             new File(new File(new File(x, "java"), "lang"), "Object.java").getPath()};
  74         compile(jcArgs);
  75 
  76         String[] jpArgs = { "-classpath", ".", "-c", "E" };
  77 
  78         StringWriter sw = new StringWriter();
  79         javap(new PrintWriter(sw, true), jpArgs);
  80         check(sw.toString(), "// Method java/lang/System.arraycopy:(Ljava/lang/Object;ILjava/lang/Object;II)V");
  81         callValues();
  82     }
  83 
  84     void compile(String... args) {
  85         int rc = com.sun.tools.javac.Main.compile(args);
  86         if (rc != 0)
  87             throw new Error("javac failed: " + Arrays.asList(args) + ": " + rc);
  88     }
  89 
  90     void javap(PrintWriter out, String... args) throws Exception {
  91         int rc = com.sun.tools.javap.Main.run(args, out);
  92         if (rc != 0)
  93             throw new Error("javap failed: " + Arrays.asList(args) + ": " + rc);
  94     }
  95 
  96     void check(String s, String require) {
  97         System.out.println("Checking:\n" + s);
  98         if (s.indexOf(require) == -1) {
  99             System.err.println("Can't find " + require);
 100             errors++;
 101         }
 102     }
 103 
 104     void callValues() {
 105         try {
 106             File dot = new File(System.getProperty("user.dir"));
 107             ClassLoader cl = new URLClassLoader(new URL[] { dot.toURL() });
 108             Class<?> e_class = cl.loadClass("E");
 109             Method m = e_class.getMethod("values", new Class[] { });
 110             //System.err.println(m);
 111             Object o = m.invoke(null, (Object[]) null);
 112             List<Object> v = Arrays.asList((Object[]) o);
 113             if (!v.toString().equals("[a, b, c]"))
 114                 throw new Error("unexpected result for E.values(): " + v);
 115         } catch (Exception e) {
 116             throw new Error(e);
 117         }
 118     }
 119 
 120     int errors;
 121 }
 122