@Override public void visitClassContext(ClassContext classContext) { if (!enabled()) { return; } JavaClass jClass = classContext.getJavaClass(); XClass xClass = classContext.getXClass(); try { if (!isJunit3TestCase(xClass)) { return; } if ((jClass.getAccessFlags() & ACC_ABSTRACT) == 0) { if (!hasTestMethods(jClass)) { bugReporter.reportBug( new BugInstance(this, "IJU_NO_TESTS", LOW_PRIORITY).addClass(jClass)); } } directChildOfTestCase = "junit.framework.TestCase".equals(jClass.getSuperclassName()); jClass.accept(this); } catch (ClassNotFoundException cnfe) { bugReporter.reportMissingClass(cnfe); } }
/** * Dumps the contents of the specified class to the specified directory. The file is named * dump_dir/[class].bcel. It contains a synopsis of the fields and methods followed by the jvm * code for each method. * * @param jc javaclass to dump * @param dump_dir directory in which to write the file */ public static void dump(JavaClass jc, File dump_dir) { try { dump_dir.mkdir(); File path = new File(dump_dir, jc.getClassName() + ".bcel"); PrintStream p = new PrintStream(path); // Print the class, super class and interfaces p.printf("class %s extends %s\n", jc.getClassName(), jc.getSuperclassName()); String[] inames = jc.getInterfaceNames(); if ((inames != null) && (inames.length > 0)) { p.printf(" "); for (String iname : inames) p.printf("implements %s ", iname); p.printf("\n"); } // Print each field p.printf("\nFields\n"); for (Field f : jc.getFields()) p.printf(" %s\n", f); // Print the signature of each method p.printf("\nMethods\n"); for (Method m : jc.getMethods()) p.printf(" %s\n", m); // If this is not an interface, print the code for each method if (!jc.isInterface()) { for (Method m : jc.getMethods()) { p.printf("\nMethod %s\n", m); Code code = m.getCode(); if (code != null) p.printf(" %s\n", code.toString().replace("\n", "\n ")); } } // Print the details of the constant pool. p.printf("Constant Pool:\n"); ConstantPool cp = jc.getConstantPool(); Constant[] constants = cp.getConstantPool(); for (int ii = 0; ii < constants.length; ii++) { p.printf(" %d %s\n", ii, constants[ii]); } p.close(); } catch (Exception e) { throw new Error("Unexpected error dumping javaclass", e); } }
@Override public void visit(JavaClass obj) { String superClassname = obj.getSuperclassName(); // System.out.println("superclass of " + getClassName() + " is " + superClassname); isEnum = superClassname.equals("java.lang.Enum"); if (isEnum) return; int flags = obj.getAccessFlags(); isAbstract = (flags & ACC_ABSTRACT) != 0 || (flags & ACC_INTERFACE) != 0; isAnonymousInnerClass = anonymousInnerClassNamePattern.matcher(getClassName()).matches(); innerClassHasOuterInstance = false; for (Field f : obj.getFields()) { if (f.getName().equals("this$0")) { innerClassHasOuterInstance = true; break; } } sawSerialVersionUID = false; isSerializable = implementsSerializableDirectly = false; isExternalizable = false; directlyImplementsExternalizable = false; isGUIClass = false; isEjbImplClass = false; seenTransientField = false; // boolean isEnum = obj.getSuperclassName().equals("java.lang.Enum"); fieldsThatMightBeAProblem.clear(); transientFieldsUpdates.clear(); transientFieldsSetInConstructor.clear(); transientFieldsSetToDefaultValueInConstructor.clear(); // isRemote = false; // Does this class directly implement Serializable? String[] interface_names = obj.getInterfaceNames(); for (String interface_name : interface_names) { if (interface_name.equals("java.io.Externalizable")) { directlyImplementsExternalizable = true; isExternalizable = true; if (DEBUG) { System.out.println("Directly implements Externalizable: " + getClassName()); } } else if (interface_name.equals("java.io.Serializable")) { implementsSerializableDirectly = true; isSerializable = true; if (DEBUG) { System.out.println("Directly implements Serializable: " + getClassName()); } break; } } // Does this class indirectly implement Serializable? if (!isSerializable) { if (Subtypes2.instanceOf(obj, "java.io.Externalizable")) { isExternalizable = true; if (DEBUG) { System.out.println("Indirectly implements Externalizable: " + getClassName()); } } if (Subtypes2.instanceOf(obj, "java.io.Serializable")) { isSerializable = true; if (DEBUG) { System.out.println("Indirectly implements Serializable: " + getClassName()); } } } hasPublicVoidConstructor = false; superClassHasVoidConstructor = true; superClassHasReadObject = false; superClassImplementsSerializable = isSerializable && !implementsSerializableDirectly; ClassDescriptor superclassDescriptor = getXClass().getSuperclassDescriptor(); if (superclassDescriptor != null) try { XClass superXClass = Global.getAnalysisCache().getClassAnalysis(XClass.class, superclassDescriptor); if (superXClass != null) { superClassImplementsSerializable = AnalysisContext.currentAnalysisContext() .getSubtypes2() .isSubtype( superXClass.getClassDescriptor(), DescriptorFactory.createClassDescriptor(java.io.Serializable.class)); superClassHasVoidConstructor = false; for (XMethod m : superXClass.getXMethods()) { if (m.getName().equals("<init>") && m.getSignature().equals("()V") && !m.isPrivate()) { superClassHasVoidConstructor = true; } if (m.getName().equals("readObject") && m.getSignature().equals("(Ljava/io/ObjectInputStream;)V") && m.isPrivate()) superClassHasReadObject = true; } } } catch (ClassNotFoundException e) { bugReporter.reportMissingClass(e); } catch (CheckedAnalysisException e) { bugReporter.logError("huh", e); } // Is this a GUI or other class that is rarely serialized? isGUIClass = false; isEjbImplClass = false; if (true || !directlyImplementsExternalizable && !implementsSerializableDirectly) { isEjbImplClass = Subtypes2.instanceOf(obj, "javax.ejb.SessionBean"); isGUIClass = (Subtypes2.instanceOf(obj, "java.lang.Throwable") || Subtypes2.instanceOf(obj, "java.awt.Component") || Subtypes2.instanceOf(obj, "java.awt.Component$AccessibleAWTComponent") || Subtypes2.instanceOf(obj, "java.awt.event.ActionListener") || Subtypes2.instanceOf(obj, "java.util.EventListener")); if (!isGUIClass) { JavaClass o = obj; while (o != null) { if (o.getClassName().startsWith("java.awt") || o.getClassName().startsWith("javax.swing")) { isGUIClass = true; break; } try { o = o.getSuperClass(); } catch (ClassNotFoundException e) { break; } } } } foundSynthetic = false; foundSynchronizedMethods = false; writeObjectIsSynchronized = false; sawReadExternal = sawWriteExternal = sawReadObject = sawReadResolve = sawWriteObject = false; if (isSerializable) { for (Method m : obj.getMethods()) { if (m.getName().equals("readObject") && m.getSignature().equals("(Ljava/io/ObjectInputStream;)V")) sawReadObject = true; else if (m.getName().equals("readResolve") && m.getSignature().startsWith("()")) sawReadResolve = true; else if (m.getName().equals("readObjectNoData") && m.getSignature().equals("()V")) sawReadObject = true; else if (m.getName().equals("writeObject") && m.getSignature().equals("(Ljava/io/ObjectOutputStream;)V")) sawWriteObject = true; } for (Field f : obj.getFields()) { if (f.isTransient()) seenTransientField = true; } } }