📄 basepreverifytestcase.java
字号:
* @param classNode
*/
private void sortLocalVariables(ClassNode classNode) {
LocalVariableComparator comparator =
new LocalVariableComparator();
Iterator methods = classNode.methods.iterator();
while (methods.hasNext()) {
MethodNode method = (MethodNode) methods.next();
if (method.localVariables != null) {
Collections.sort(method.localVariables, comparator);
}
}
}
/**
* Sort the try catch blocks so that the string output matches.
*
* @param classNode
*/
private void sortTryCatchBlocks(ClassNode classNode) {
TryCatchBlockComparator comparator =
new TryCatchBlockComparator();
Iterator methods = classNode.methods.iterator();
while (methods.hasNext()) {
MethodNode method = (MethodNode) methods.next();
if (method.tryCatchBlocks != null) {
Collections.sort(method.tryCatchBlocks, comparator);
}
}
}
/**
* Dump the disassembled class node for debugging purposes.
*
* @param classNode
* @param subdirectory
* @throws IOException
*/
private void dumpClassNode(ClassNode classNode, String subdirectory)
throws IOException
{
String outputDirectory = System.getProperty(DISASSEMBLE_OUTPUT);
if (outputDirectory != null) {
File outputDirFile = new File(outputDirectory);
if (outputDirFile.exists()) {
dumpClassNode(new File(outputDirFile, subdirectory), classNode);
}
}
}
/**
* Dump the disassembled class node into the specified output
* directory.
*
* @param outputDirectory
* @param classNode
* @throws FileNotFoundException
*/
protected void dumpClassNode(File outputDirectory, ClassNode classNode)
throws IOException
{
String className = classNode.name;
File outputFile = new File(outputDirectory, className + ".txt");
outputFile.getParentFile().mkdirs();
FileWriter fileWriter = new FileWriter(outputFile);
PrintWriter printWriter = new PrintWriter(fileWriter);
TraceClassVisitor visitor = new TraceClassVisitor(printWriter);
classNode.accept(visitor);
printWriter.close();
}
/**
* Get the property value correctly resolved.
*
* @param propValue
* @return
*/
private String getResolvedPropertyValue(String key) {
Properties props = System.getProperties();
String value = props.getProperty(key);
if (value == null) value = "";
int offset = 0;
StringBuffer sb = new StringBuffer(value);
Matcher matcher = PROPS_PATTERN.matcher(sb);
while (matcher.find(offset)) {
String referencedProp = matcher.group(1);
String resolvedReferenced =
getResolvedPropertyValue(referencedProp);
sb.replace(matcher.start(), matcher.end(), resolvedReferenced);
// Figure out the new offset, based on the replaced
// string length
offset = matcher.start() + resolvedReferenced.length();
value = sb.toString();
props.setProperty(key, value);
}
return value;
}
/**
* @param testRoot
* @param className
* @param preverifyProgram
* @return
* @throws FileNotFoundException
*/
protected InputStream getWTKPreverifiedOutput(
TestPreverificationPolicy policy,
String className)
throws IOException
{
File tempDir = getTemporaryDirectory();
wtkPreverify(policy, className, tempDir);
File outputClass = new File(tempDir, className.replace('.', '/') + ".class");
if (!outputClass.exists()) fail("Comparison type not found");
return new FileInputStream(outputClass);
}
private void wtkPreverify(
TestPreverificationPolicy policy,
String className,
File tempDir)
throws IOException
{
String wtkRoot = getResolvedPropertyValue(WTK_ROOT_PROPERTY);
if (wtkRoot == null) fail("Invalid WTK root value");
File wtkRootFile = new File(wtkRoot);
if (!wtkRootFile.exists()) fail("Invalid WTK root value");
File wtkBin = new File(wtkRootFile, "bin");
String[] paramArray = getPreverifyArguments(policy, className, tempDir, wtkBin);
Process process = Runtime.getRuntime().exec(paramArray, null, wtkBin);
new ProcessOutputPump("out", process.getInputStream(), System.out).start();
new ProcessOutputPump("err", process.getErrorStream(), System.err).start();
try {
int exitValue = process.waitFor();
if (exitValue != 0) {
fail("Error preverifying via WTK");
}
} catch (InterruptedException e) {
fail(e);
}
}
/**
* @param policy
* @param testRoot
* @param className
* @param tempDir
* @param wtkBin
* @return
*/
private String[] getPreverifyArguments(
TestPreverificationPolicy policy,
String className,
File tempDir,
File wtkBin)
{
File preverify = new File(wtkBin, "preverify");
File inputsRoot = getWTKInputDirectory();
String classpath = getPreverifyClasspath(policy, inputsRoot);
ArrayList params = new ArrayList();
params.add(preverify.toString());
params.add("-classpath");
params.add(classpath);
params.add("-d");
params.add(tempDir.toString());
if (!policy.areFinalizersAllowed())
params.add("-nofinalize");
if (!policy.areNativeMethodsAllowed())
params.add("-nonative");
if (!policy.isFloatingPointAllowed())
params.add("-nofp");
params.add(className);
return (String[]) params.toArray(new String[params.size()]);
}
/**
* @return
*/
protected File getWTKInputDirectory() {
String inputsProperty = getResolvedPropertyValue(TEST_INPUTS_PROPERTY);
return new File(inputsProperty);
}
/**
* @param policy
* @param inputsRoot
* @return
*/
private String getPreverifyClasspath(TestPreverificationPolicy policy, File inputsRoot) {
String baseClasspath = getResolvedPropertyValue(BASE_CLASSPATH_PROPERTY);
StringBuffer classpath = new StringBuffer();
classpath
.append(inputsRoot.toString())
.append(File.pathSeparatorChar)
.append(policy.getClasspath().replace('/', File.separatorChar));
if (baseClasspath != null) {
classpath
.append(File.pathSeparatorChar)
.append(baseClasspath);
}
return classpath.toString();
}
/**
* Get a temporary directory.
*
* @return
* @throws IOException
*/
private File getTemporaryDirectory()
throws IOException
{
File tempDir = File.createTempFile("preverify_", "dir");
tempDir.delete();
if (!tempDir.mkdirs()) {
fail("failed to create temporary directory");
}
return tempDir;
}
/**
* Fail with the specified exception.
* @param e
*/
protected void fail(Exception e) {
e.printStackTrace();
fail(e.toString());
}
/**
* Return the name of the class specified by the results.
*
* @param results
* @return
*/
protected String getClassName(PreverificationResults results) {
return results.getPreverifiedClassNode().name.replace('/', '.');
}
protected String getClasspathProperty(String propertyName) {
String path = getResolvedPropertyValue(propertyName);
if (path == null) {
fail("Library property " + propertyName + " not found");
}
return path;
}
/**
* Get a ClassNode instance for the specified input stream.
*
* @param classStream
* @return
* @throws IOException
*/
protected ClassNode getClassNode(InputStream classStream)
throws IOException
{
// Force label resolution
ClassNode classNode = new ClassNode();
ClassReader classReader = new ClassReader(classStream);
classReader.accept(classNode, new Attribute[] { new ASMStackMapAttribute() }, false);
ClassWriter writer = new ClassWriter(true);
classNode.accept(writer);
writer.toByteArray();
return classNode;
}
protected URL[] getLibrariesForProperty(String propertyName) {
URL[] urls = null;
String path = getClasspathProperty(propertyName);
String[] names = path.split(File.pathSeparator);
urls = new URL[names.length];
try {
for (int i = 0; i < names.length; i++) {
String name = names[i];
File file = new File(name);
urls[i] = file.toURL();
}
} catch (MalformedURLException e) {
fail(e);
}
return urls;
}
/**
* @param className
* @return
*/
protected InputStream getSourceClassStream(String className) {
String resourceName = "/" + className.replace('.', '/') + ".class";
return getClass().getResourceAsStream(resourceName);
}
/**
* @param className
* @param preverifiedClass
* @return
* @throws IllegalAccessException
* @throws InstantiationException
*/
protected ITestable loadTestable(String className, byte[] preverifiedClass)
throws InstantiationException, IllegalAccessException
{
TestClassLoader loader = new TestClassLoader(this.getClass().getClassLoader());
Class testableClass = loader.defineClass(className, preverifiedClass);
return (ITestable) testableClass.newInstance();
}
/**
* @see junit.framework.TestCase#setUp()
*/
protected void setUp() throws Exception {
super.setUp();
loadProperties();
}
/**
* Test the output of the preverifier against the WTK output.
*
* @param testClass
* @param policy
*/
protected void testAgainstWTK(String testClass, TestPreverificationPolicy policy) {
ClassPreverifier preverifier = new ClassPreverifier(policy);
InputStream classStream = getSourceClassStream(testClass);
assertNotNull(classStream);
try {
PreverificationResults results = preverifier.preverify(classStream, new URL[0]);
assertTrue("No errors expected", !results.isErrorResult());
byte[] preverifiedClass = results.getPreverifiedClassBytes();
assertNotNull("Code Stream bytes should not be null", preverifiedClass);
FileOutputStream fos = new FileOutputStream("c:/temp/preverified.class");
fos.write(preverifiedClass);
fos.close();
// Attempt to load the testable and check its validity
verifyBytecode(preverifiedClass);
String className = getClassName(results);
// Do a deeper comparison...
compareWithPreverifierBinary(policy, className, preverifiedClass);
} catch (Exception e) {
fail(e);
}
}
/**
* Load the test properties into the system properties.
*/
private void loadProperties() {
InputStream is = getClass().getClassLoader().getResourceAsStream("test.properties");
if (is == null) {
System.out.println("test.properties not found");
} else {
try {
System.getProperties().load(is);
} catch (IOException e) {
fail(e);
} finally {
try { is.close(); } catch (IOException e) {}
}
}
}
/**
* Attempt to run the preverified class byte codes through the ASM
* verifier.
*
* @param preverifiedClass
* @throws AnalyzerException
*/
protected void verifyBytecode(byte[] preverifiedClass) {
StringBuffer sb = new StringBuffer();
SimpleVerifier verifier = new SimpleVerifier();
Analyzer analyzer = new Analyzer(verifier);
ClassNode classNode = new ClassNode();
ClassReader classReader = new ClassReader(preverifiedClass);
classReader.accept(classNode, true);
Iterator methods = classNode.methods.iterator();
while (methods.hasNext()) {
MethodNode methodNode = (MethodNode) methods.next();
try {
analyzer.analyze(classNode.name, methodNode);
} catch (AnalyzerException e) {
sb
.append('\n')
.append("Method ")
.append(methodNode.name)
.append(": ")
.append(e.toString());
System.out.println(sb);
try {
dumpClassNode(classNode, "eclipseme");
} catch (IOException e1) {
e1.printStackTrace();
}
fail(e);
}
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -