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 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 testJavapCompare()49 public void testJavapCompare() throws Exception { 50 testClassOnPath("target/test-classes/Java8Example.class"); 51 } 52 testClassOnPath(final String javaClass)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 canonHashRef(String input)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 exec(final File workDir, final String... args)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 } 103