⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 serializableidiom.java

📁 A static analysis tool to find bugs in Java programs
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
/* * FindBugs - Find bugs in Java programs * Copyright (C) 2003,2004 University of Maryland *  * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. *  * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU * Lesser General Public License for more details. *  * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */package edu.umd.cs.findbugs.detect;import java.util.HashMap;import java.util.HashSet;import java.util.LinkedList;import java.util.List;import java.util.Map;import java.util.regex.Pattern;import org.apache.bcel.Repository;import org.apache.bcel.classfile.Attribute;import org.apache.bcel.classfile.Code;import org.apache.bcel.classfile.Field;import org.apache.bcel.classfile.FieldOrMethod;import org.apache.bcel.classfile.JavaClass;import org.apache.bcel.classfile.Method;import org.apache.bcel.classfile.Synthetic;import edu.umd.cs.findbugs.DeepSubtypeAnalysis;import edu.umd.cs.findbugs.BugInstance;import edu.umd.cs.findbugs.BugReporter;import edu.umd.cs.findbugs.BytecodeScanningDetector;import edu.umd.cs.findbugs.OpcodeStack;import edu.umd.cs.findbugs.SystemProperties;import edu.umd.cs.findbugs.OpcodeStack.Item;import edu.umd.cs.findbugs.ba.ClassContext;import edu.umd.cs.findbugs.ba.XFactory;import edu.umd.cs.findbugs.ba.XField;public class SerializableIdiom extends BytecodeScanningDetector		{	final static boolean reportTransientFieldOfNonSerializableClass =		SystemProperties.getBoolean("reportTransientFieldOfNonSerializableClass");	boolean sawSerialVersionUID;	boolean isSerializable, implementsSerializableDirectly;	boolean isExternalizable;	boolean isGUIClass;	boolean foundSynthetic;	boolean seenTransientField;	boolean foundSynchronizedMethods;	boolean writeObjectIsSynchronized;	private BugReporter bugReporter;	boolean isAbstract;	private List<BugInstance> fieldWarningList = new LinkedList<BugInstance>();	private HashMap<String, XField> fieldsThatMightBeAProblem = new HashMap<String, XField>();	private HashMap<String, XField> transientFields = new HashMap<String, XField>();	private HashMap<String, Integer> transientFieldsUpdates = new HashMap<String, Integer>();	private HashSet<String> transientFieldsSetInConstructor = new HashSet<String>();	private boolean sawReadExternal;	private boolean sawWriteExternal;	private boolean sawReadObject;	private boolean sawReadResolve;	private boolean sawWriteObject;	private boolean superClassImplementsSerializable;	private boolean hasPublicVoidConstructor;	private boolean superClassHasVoidConstructor;	private boolean directlyImplementsExternalizable;	//private JavaClass serializable;	//private JavaClass collection;	//private JavaClass map;	//private boolean isRemote;	public SerializableIdiom(BugReporter bugReporter) {		this.bugReporter = bugReporter;		//try {			//serializable = Repository.lookupClass("java.io.Serializable");			//collection = Repository.lookupClass("java.util.Collection");			//map = Repository.lookupClass("java.util.Map");			//} catch (ClassNotFoundException e) {				// can't do anything				//}	}	@Override		 public void visitClassContext(ClassContext classContext) {		classContext.getJavaClass().accept(this);		flush();	}	private void flush() {		if (!isAbstract &&				!((sawReadExternal && sawWriteExternal) || (sawReadObject && sawWriteObject))) {			for (BugInstance aFieldWarningList : fieldWarningList)				bugReporter.reportBug(aFieldWarningList);		}		fieldWarningList.clear();	}	static final Pattern anonymousInnerClassNamePattern =			Pattern.compile(".+\\$\\d+");	boolean isAnonymousInnerClass;	boolean innerClassHasOuterInstance;	private boolean isEnum;	@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;		seenTransientField = false;		// boolean isEnum = obj.getSuperclassName().equals("java.lang.Enum");		fieldsThatMightBeAProblem.clear();		transientFields.clear();		transientFieldsUpdates.clear();		transientFieldsSetInConstructor.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;				// System.out.println("Directly implements Externalizable: " + betterClassName);			} else if (interface_name.equals("java.io.Serializable")) {				implementsSerializableDirectly = true;				isSerializable = true;				break;			}		}		// Does this class indirectly implement Serializable?		if (!isSerializable) {			try {				if (Repository.instanceOf(obj, "java.io.Externalizable"))					isExternalizable = true;				if (Repository.instanceOf(obj, "java.io.Serializable"))					isSerializable = true;/*			if (Repository.instanceOf(obj,"java.rmi.Remote")) {			isRemote = true;			}*/			} catch (ClassNotFoundException e) {				bugReporter.reportMissingClass(e);			}		}		hasPublicVoidConstructor = false;		superClassHasVoidConstructor = true;		superClassImplementsSerializable = isSerializable && !implementsSerializableDirectly;		try {			JavaClass superClass = obj.getSuperClass();			if (superClass != null) {				Method[] superClassMethods = superClass.getMethods();				superClassImplementsSerializable = Repository.instanceOf(superClass,						"java.io.Serializable");				superClassHasVoidConstructor = false;				for (Method m : superClassMethods) {					/*											if (!m.isPrivate())											System.out.println("Supercase of " + className												+ " has an accessible method named " + m.getName()												+ " with sig " + m.getSignature());											*/					if (m.getName().equals("<init>")							&& m.getSignature().equals("()V")							&& !m.isPrivate()							) {						// System.out.println("  super has void constructor");						superClassHasVoidConstructor = true;						break;					}				}			}		} catch (ClassNotFoundException e) {			bugReporter.reportMissingClass(e);		}		// Is this a GUI  or other class that is rarely serialized?		try {			isGUIClass = 			 Repository.instanceOf(obj, "java.lang.Throwable")			|| Repository.instanceOf(obj, "java.awt.Component")			|| Repository.implementationOf(obj, "java.awt.event.ActionListener")			|| Repository.implementationOf(obj, "java.util.EventListener")			;		} catch (ClassNotFoundException e) {			bugReporter.reportMissingClass(e);		}		foundSynthetic = false;		foundSynchronizedMethods = false;		writeObjectIsSynchronized = false;		sawReadExternal = sawWriteExternal = sawReadObject = sawReadResolve = sawWriteObject = false;	}	@Override		 public void visitAfter(JavaClass obj) {		if (isEnum) return;		if (false) {			System.out.println(getDottedClassName());			System.out.println("  hasPublicVoidConstructor: " + hasPublicVoidConstructor);			System.out.println("  superClassHasVoidConstructor: " + superClassHasVoidConstructor);			System.out.println("  isExternalizable: " + isExternalizable);			System.out.println("  isSerializable: " + isSerializable);			System.out.println("  isAbstract: " + isAbstract);			System.out.println("  superClassImplementsSerializable: " + superClassImplementsSerializable);		}		if (isSerializable && !sawReadObject && !sawReadResolve && seenTransientField) {			for(Map.Entry<String,Integer> e : transientFieldsUpdates.entrySet()) {					XField fieldX = transientFields.get(e.getKey());					int priority = NORMAL_PRIORITY;					if (transientFieldsSetInConstructor.contains(e.getKey()))						priority--;					else {						if (isGUIClass) priority++;						if (e.getValue() < 3) 							priority++;					}					try {						double isSerializable = DeepSubtypeAnalysis.isDeepSerializable(fieldX.getSignature());						if (isSerializable < 0.6) priority++;					} catch (ClassNotFoundException e1) {						// ignore it					}					bugReporter.reportBug(new BugInstance(this, "SE_TRANSIENT_FIELD_NOT_RESTORED",							priority )							.addClass(getThisClass())							.addField(fieldX));			}		}		if (isSerializable && !isExternalizable				&& !superClassHasVoidConstructor				&& !superClassImplementsSerializable)			bugReporter.reportBug(new BugInstance(this, "SE_NO_SUITABLE_CONSTRUCTOR",

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -