1 /*
   2  * Copyright (c) 2010, 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 4942232
  27  * @summary missing param class processes without error
  28  * @modules jdk.compiler/com.sun.tools.javah
  29  * @build ParamClassTest Test
  30  * @run main Test
  31  */
  32 
  33 import java.io.*;
  34 import java.util.*;
  35 
  36 public class Test {
  37     public static void main(String... args) throws Exception {
  38         new Test().run();
  39     }
  40 
  41     void run() throws Exception {
  42         File testSrc = new File(System.getProperty("test.src"));
  43         File testClasses = new File(System.getProperty("test.classes"));
  44 
  45         // standard use of javah on valid class file
  46         String[] test1Args = {
  47             "-d", mkdir("test1/out").getPath(),
  48             "-classpath", testClasses.getPath(),
  49             "ParamClassTest"
  50         };
  51         test(test1Args, 0);
  52 
  53         // extended use of javah on valid source file
  54         String[] test2Args = {
  55             "-d", mkdir("test2/out").getPath(),
  56             "-classpath", testSrc.getPath(),
  57             "ParamClassTest"
  58         };
  59         test(test2Args, 0);
  60 
  61         // javah on class file with missing referents
  62         File test3Classes = mkdir("test3/classes");
  63         copy(new File(testClasses, "ParamClassTest.class"), test3Classes);
  64         String[] test3Args = {
  65             "-d", mkdir("test3/out").getPath(),
  66             "-classpath", test3Classes.getPath(),
  67             "ParamClassTest"
  68         };
  69         test(test3Args, 1);
  70 
  71         // javah on source file with missing referents
  72         File test4Src = mkdir("test4/src");
  73         String paramClassTestSrc = readFile(new File(testSrc, "ParamClassTest.java"));
  74         writeFile(new File(test4Src, "ParamClassTest.java"),
  75                 paramClassTestSrc.replaceAll("class Param \\{\\s+\\}", ""));
  76         String[] test4Args = {
  77             "-d", mkdir("test4/out").getPath(),
  78             "-classpath", test4Src.getPath(),
  79             "ParamClassTest"
  80         };
  81         test(test4Args, 15);
  82 
  83         if (errors > 0)
  84             throw new Exception(errors + " errors occurred");
  85     }
  86 
  87     void test(String[] args, int expect) {
  88         System.err.println("test: " + Arrays.asList(args));
  89         int rc = javah(args);
  90         if (rc != expect)
  91             error("Unexpected return code: " + rc + "; expected: " + expect);
  92     }
  93 
  94     int javah(String... args) {
  95         StringWriter sw = new StringWriter();
  96         PrintWriter pw = new PrintWriter(sw);
  97         int rc = com.sun.tools.javah.Main.run(args, pw);
  98         pw.close();
  99         String out = sw.toString();
 100         if (!out.isEmpty())
 101             System.err.println(out);
 102         return rc;
 103     }
 104 
 105     File mkdir(String path) {
 106         File f = new File(path);
 107         f.mkdirs();
 108         return f;
 109     }
 110 
 111     void copy(File from, File to) throws IOException {
 112         if (to.isDirectory())
 113             to = new File(to, from.getName());
 114         try (DataInputStream in = new DataInputStream(new FileInputStream(from));
 115                 FileOutputStream out = new FileOutputStream(to)) {
 116             byte[] buf = new byte[(int) from.length()];
 117             in.readFully(buf);
 118             out.write(buf);
 119         }
 120     }
 121 
 122     String readFile(File f) throws IOException {
 123         try (DataInputStream in = new DataInputStream(new FileInputStream(f))) {
 124             byte[] buf = new byte[(int) f.length()];
 125             in.readFully(buf);
 126             return new String(buf);
 127         }
 128     }
 129 
 130     void writeFile(File f, String body) throws IOException {
 131         try (FileWriter out = new FileWriter(f)) {
 132             out.write(body);
 133         }
 134     }
 135 
 136     void error(String msg) {
 137         System.err.println(msg);
 138         errors++;
 139     }
 140 
 141     int errors;
 142 }