View Javadoc
1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one or more
3    * contributor license agreements.  See the NOTICE file distributed with
4    * this work for additional information regarding copyright ownership.
5    * The ASF licenses this file to You under the Apache License, Version 2.0
6    * (the "License"); you may not use this file except in compliance with
7    * the License.  You may obtain a copy of the License at
8    *
9    *      http://www.apache.org/licenses/LICENSE-2.0
10   *
11   *  Unless required by applicable law or agreed to in writing, software
12   *  distributed under the License is distributed on an "AS IS" BASIS,
13   *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   *  See the License for the specific language governing permissions and
15   *  limitations under the License.
16   *
17   */
18  package org.apache.bcel.util;
19  
20  import static org.junit.Assert.*;
21  
22  import java.io.BufferedInputStream;
23  import java.io.ByteArrayOutputStream;
24  import java.io.File;
25  import java.io.FileOutputStream;
26  import java.io.InputStream;
27  import java.io.OutputStream;
28  import org.apache.bcel.classfile.JavaClass;
29  import org.junit.Test;
30  
31  
32  public class BCELifierTestCase {
33  
34      @Test
35      public void test() throws Exception {
36          final OutputStream os = new ByteArrayOutputStream();
37          final JavaClass java_class = BCELifier.getJavaClass("Java8Example");
38          assertNotNull(java_class);
39          final BCELifier bcelifier = new BCELifier(java_class, os);
40          bcelifier.start();
41      }
42  
43      /*
44       * Dump a class using "javap" and compare with the same class recreated
45       * using BCELifier, "javac", "java" and dumped with "javap"
46       * TODO: detect if JDK present and skip test if not
47       */
48      @Test
49      public void testJavapCompare() throws Exception {
50          testClassOnPath("target/test-classes/Java8Example.class");
51      }
52  
53      private void testClassOnPath(final String javaClass) throws Exception {
54          // Get javap of the input class
55          final String initial = exec(null, "javap", "-p", "-c", javaClass);
56  
57          final File workDir = new File("target");
58          final File infile = new File(javaClass);
59          final JavaClass java_class = BCELifier.getJavaClass(infile.getName().replace(".class", ""));
60          assertNotNull(java_class);
61          final File outfile = new File(workDir, infile.getName().replace(".class", "Creator.java"));
62          try (FileOutputStream fos = new FileOutputStream(outfile)) {
63              final BCELifier bcelifier = new BCELifier(java_class, fos);
64              bcelifier.start();
65          }
66          exec(workDir, "javac", "-cp", "classes", outfile.getName());
67          exec(workDir, "java", "-cp", "." + File.pathSeparator + "classes", outfile.getName().replace(".java", ""));
68          final String output = exec(workDir, "javap", "-p", "-c", infile.getName());
69          assertEquals(canonHashRef(initial), canonHashRef(output));
70      }
71  
72      // Canonicalise the javap output so it compares better
73      private String canonHashRef(String input) {
74          input = input.replaceAll("#\\d+", "#n"); // numbers may vary in length
75          input = input.replaceAll(" +", " "); // collapse spaces
76          input = input.replaceAll("//.+",""); // comments may vary
77          return input;
78      }
79  
80      private String exec(final File workDir, final String... args) throws Exception {
81          // System.err.println(java.util.Arrays.toString(args));
82          final ProcessBuilder pb = new ProcessBuilder(args);
83          pb.directory(workDir);
84          final Process proc = pb.start();
85          try (BufferedInputStream is = new BufferedInputStream(proc.getInputStream());
86                  InputStream es = proc.getErrorStream()) {
87              proc.waitFor();
88              final byte[] buff = new byte[2048];
89              int len;
90              while ((len = es.read(buff)) != -1) {
91                  System.err.print(new String(buff, 0, len));
92              }
93  
94              final StringBuilder sb = new StringBuilder();
95              while ((len = is.read(buff)) != -1) {
96                  sb.append(new String(buff, 0, len));
97              }
98              return sb.toString();
99          }
100     }
101 
102 }