Java tutorial
/* * dex2jar - Tools to work with android .dex and java .class files * Copyright (c) 2009-2012 Panxiaobo * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.googlecode.dex2jar.v3; import java.io.File; import java.io.IOException; import java.io.OutputStreamWriter; import java.io.PrintWriter; import java.io.StringWriter; import java.util.HashMap; import java.util.Map; import java.util.zip.ZipEntry; import java.util.zip.ZipOutputStream; import org.apache.commons.io.FileUtils; import org.objectweb.asm.Type; import org.objectweb.asm.tree.MethodNode; import com.googlecode.dex2jar.Method; import com.googlecode.dex2jar.ir.Constant; import com.googlecode.dex2jar.ir.ET; import com.googlecode.dex2jar.ir.IrMethod; import com.googlecode.dex2jar.ir.Value; import com.googlecode.dex2jar.ir.expr.Exprs; import com.googlecode.dex2jar.ir.stmt.Stmts; import com.googlecode.dex2jar.reader.DexFileReader; import com.googlecode.dex2jar.util.ASMifierCodeV; import com.googlecode.dex2jar.util.Escape; import com.googlecode.dex2jar.util.Out; import com.googlecode.dex2jar.visitors.DexClassVisitor; import com.googlecode.dex2jar.visitors.DexCodeVisitor; import com.googlecode.dex2jar.visitors.DexMethodVisitor; import com.googlecode.dex2jar.visitors.EmptyVisitor; public class DexExceptionHandlerImpl implements DexExceptionHandler { private int readerConfig = DexFileReader.SKIP_DEBUG; private Map<Method, Exception> exceptions = new HashMap<Method, Exception>(); public Map<Method, Exception> getExceptions() { return exceptions; } @Override public void handleFileException(Exception e) { e.printStackTrace(System.err); } @Override public void handleMethodTranslateException(Method method, IrMethod irMethod, MethodNode methodNode, Exception e) { this.exceptions.put(method, e);// record the exception // replace the generated code with // 'return new RuntimeException("Generated by Dex2jar, and Some Exception Caught : xxxxxxxxxxxxx");' StringWriter s = new StringWriter(); e.printStackTrace(new PrintWriter(s)); String msg = s.toString(); methodNode.instructions.clear(); methodNode.tryCatchBlocks.clear(); irMethod.traps.clear(); irMethod.stmts.clear(); irMethod.stmts.add(Stmts.nThrow(Exprs.nInvokeNew( new Value[] { Constant.nString("Generated by Dex2jar, and Some Exception Caught :" + msg), }, new Type[] { Type.getType(String.class) }, Type.getType(RuntimeException.class)))); new IrMethod2AsmMethod().convert(irMethod, methodNode); } public static String getVersionString() { return "version: reader-" + DexFileReader.class.getPackage().getImplementationVersion() + ", translator-" + Main.class.getPackage().getImplementationVersion() + ", ir-" + ET.class.getPackage().getImplementationVersion(); } public DexExceptionHandlerImpl skipDebug(boolean b) { if (b) { this.readerConfig |= DexFileReader.SKIP_DEBUG; } else { this.readerConfig &= ~DexFileReader.SKIP_DEBUG; } return this; } public DexExceptionHandlerImpl skipDebug() { this.readerConfig |= DexFileReader.SKIP_DEBUG; return this; } public void dumpException(DexFileReader reader, File errorFile) throws IOException { for (Map.Entry<Method, Exception> e : exceptions.entrySet()) { System.err.println("Error:" + e.getKey().toString() + "->" + e.getValue().getMessage()); } final ZipOutputStream errorZipOutputStream = new ZipOutputStream(FileUtils.openOutputStream(errorFile)); errorZipOutputStream.putNextEntry(new ZipEntry("summary.txt")); final PrintWriter fw = new PrintWriter(new OutputStreamWriter(errorZipOutputStream, "UTF-8")); fw.println(getVersionString()); fw.println("there are " + exceptions.size() + " error methods"); fw.print("options: "); if ((readerConfig & DexFileReader.SKIP_DEBUG) == 0) { fw.print(" -d"); } fw.println(); fw.flush(); errorZipOutputStream.closeEntry(); final Out out = new Out() { @Override public void pop() { } @Override public void push() { } @Override public void s(String s) { fw.println(s); } @Override public void s(String format, Object... arg) { fw.println(String.format(format, arg)); } }; final int[] count = new int[] { 0 }; reader.accept(new EmptyVisitor() { @Override public DexClassVisitor visit(int accessFlags, String className, String superClass, String[] interfaceNames) { return new EmptyVisitor() { @Override public DexMethodVisitor visitMethod(final int accessFlags, final Method method) { if (exceptions.containsKey(method)) { return new EmptyVisitor() { @Override public DexCodeVisitor visitCode() { try { errorZipOutputStream.putNextEntry(new ZipEntry("t" + count[0]++ + ".txt")); } catch (IOException e) { throw new RuntimeException(e); } Exception exception = exceptions.get(method); exception.printStackTrace(fw); out.s(""); out.s("DexMethodVisitor mv=cv.visitMethod(%s, %s);", Escape.methodAcc(accessFlags), Escape.v(method)); out.s("DexCodeVisitor code = mv.visitCode();"); return new ASMifierCodeV(out); } @Override public void visitEnd() { out.s("mv.visitEnd();"); fw.flush(); try { errorZipOutputStream.closeEntry(); } catch (IOException e) { throw new RuntimeException(e); } } }; } return null; } }; } }, readerConfig); errorZipOutputStream.close(); } }