Java Code Examples for org.apache.bcel.classfile.JavaClass#isInterface()

The following examples show how to use org.apache.bcel.classfile.JavaClass#isInterface() . You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example 1
Source File: ComparatorIdiom.java    From spotbugs with GNU Lesser General Public License v2.1 5 votes vote down vote up
@Override
public void visit(JavaClass obj) {

    if (Subtypes2.instanceOf(obj, "java.util.Comparator") && !ClassName.isLocalOrAnonymous(getClassName())
            && !Subtypes2.instanceOf(obj, "java.io.Serializable")) {
        int priority = NORMAL_PRIORITY;
        if (obj.isInterface() || obj.isAbstract()) {
            return;
        }

        double easilySerializable = 1.0;
        for (Field f : obj.getFields()) {
            try {
                if (f.getName().startsWith("this$")) {
                    return;
                }
                String signature = f.getSignature();
                char firstChar = signature.charAt(0);
                if (firstChar == 'L' || firstChar == '[') {
                    easilySerializable *= DeepSubtypeAnalysis.isDeepSerializable(signature);
                }
            } catch (ClassNotFoundException e) {
                easilySerializable = 0.0;
                break;
            }
        }

        if (easilySerializable < 0.9) {
            priority = LOW_PRIORITY;
        }

        bugReporter.reportBug(new BugInstance(this, "SE_COMPARATOR_SHOULD_BE_SERIALIZABLE", priority).addClass(this));

    }

}
 
Example 2
Source File: Naming.java    From spotbugs with GNU Lesser General Public License v2.1 5 votes vote down vote up
@Override
public void visitJavaClass(JavaClass obj) {
    if (BCELUtil.isSynthetic(obj)) {
        return;
    }
    String name = obj.getClassName();
    if (!visited.add(name)) {
        return;
    }

    String superClassName = obj.getSuperclassName();
    if (!Values.DOTTED_JAVA_LANG_OBJECT.equals(name)) {
        if (sameSimpleName(superClassName, name)) {
            bugReporter.reportBug(new BugInstance(this, "NM_SAME_SIMPLE_NAME_AS_SUPERCLASS", HIGH_PRIORITY).addClass(name)
                    .addClass(superClassName));
        }
        for (String interfaceName : obj.getInterfaceNames()) {
            if (sameSimpleName(interfaceName, name)) {
                bugReporter.reportBug(new BugInstance(this, "NM_SAME_SIMPLE_NAME_AS_INTERFACE", NORMAL_PRIORITY).addClass(
                        name).addClass(interfaceName));
            }
        }
    }
    if (obj.isInterface()) {
        return;
    }

    if (Values.DOTTED_JAVA_LANG_OBJECT.equals(superClassName) && !visited.contains(superClassName)) {
        try {
            visitJavaClass(obj.getSuperClass());
        } catch (ClassNotFoundException e) {
            // ignore it
        }
    }
    super.visitJavaClass(obj);
}
 
Example 3
Source File: FindMaskedFields.java    From spotbugs with GNU Lesser General Public License v2.1 5 votes vote down vote up
@Override
public void visitClassContext(ClassContext classContext) {
    JavaClass obj = classContext.getJavaClass();
    if (!obj.isInterface()) {
        classContext.getJavaClass().accept(this);
    }
}
 
Example 4
Source File: ClassFeatureSet.java    From spotbugs with GNU Lesser General Public License v2.1 5 votes vote down vote up
/**
 * Initialize from given JavaClass.
 *
 * @param javaClass
 *            the JavaClass
 * @return this object
 */
public ClassFeatureSet initialize(JavaClass javaClass) {
    this.className = javaClass.getClassName();
    this.isInterface = javaClass.isInterface();

    addFeature(CLASS_NAME_KEY + transformClassName(javaClass.getClassName()));

    for (Method method : javaClass.getMethods()) {
        if (!isSynthetic(method)) {
            String transformedMethodSignature = transformMethodSignature(method.getSignature());

            if (method.isStatic() || !overridesSuperclassMethod(javaClass, method)) {
                addFeature(METHOD_NAME_KEY + method.getName() + ":" + transformedMethodSignature);
            }

            Code code = method.getCode();
            if (code != null && code.getCode() != null && code.getCode().length >= MIN_CODE_LENGTH) {
                addFeature(CODE_LENGTH_KEY + method.getName() + ":" + transformedMethodSignature + ":"
                        + code.getCode().length);
            }
        }
    }

    for (Field field : javaClass.getFields()) {
        if (!isSynthetic(field)) {
            addFeature(FIELD_NAME_KEY + field.getName() + ":" + transformSignature(field.getSignature()));
        }
    }

    return this;
}
 
Example 5
Source File: LinkageChecker.java    From cloud-opensource-java with Apache License 2.0 4 votes vote down vote up
/**
 * Returns an {@code Optional} describing the linkage error for the method reference if the
 * reference does not have a valid referent in the input class path; otherwise an empty {@code
 * Optional}.
 *
 * @see <a href="https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-5.html#jvms-5.4.3.3">Java
 *     Virtual Machine Specification: 5.4.3.3. Method Resolution</a>
 * @see <a href="https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-5.html#jvms-5.4.3.4">Java
 *     Virtual Machine Specification: 5.4.3.4. Interface Method Resolution</a>
 */
@VisibleForTesting
Optional<SymbolProblem> findSymbolProblem(ClassFile classFile, MethodSymbol symbol) {
  String sourceClassName = classFile.getBinaryName();
  String targetClassName = symbol.getClassBinaryName();
  String methodName = symbol.getName();

  // Skip references to Java runtime class. For example, java.lang.String.
  if (classDumper.isSystemClass(targetClassName)) {
    return Optional.empty();
  }

  try {
    JavaClass targetJavaClass = classDumper.loadJavaClass(targetClassName);
    ClassPathEntry classFileLocation = classDumper.findClassLocation(targetClassName);
    ClassFile containingClassFile =
        classFileLocation == null ? null : new ClassFile(classFileLocation, targetClassName);

    if (!isClassAccessibleFrom(targetJavaClass, sourceClassName)) {
      return Optional.of(
          new SymbolProblem(symbol, ErrorType.INACCESSIBLE_CLASS, containingClassFile));
    }

    if (targetJavaClass.isInterface() != symbol.isInterfaceMethod()) {
      return Optional.of(
          new SymbolProblem(symbol, ErrorType.INCOMPATIBLE_CLASS_CHANGE, containingClassFile));
    }

    // Check the existence of the parent class or interface for the class
    Optional<SymbolProblem> parentSymbolProblem = findParentSymbolProblem(targetClassName);
    if (parentSymbolProblem.isPresent()) {
      return parentSymbolProblem;
    }

    // Checks the target class, its parent classes, and its interfaces.
    // Interface check is needed to avoid false positive for a method reference to an abstract
    // class that implements an interface. For example, Guava's ImmutableList is an abstract class
    // that implements the List interface, but the class does not have a get() method. A method
    // reference to ImmutableList.get() should not be reported as a linkage error.
    Iterable<JavaClass> typesToCheck =
        Iterables.concat(
            getClassHierarchy(targetJavaClass),
            Arrays.asList(targetJavaClass.getAllInterfaces()));
    for (JavaClass javaClass : typesToCheck) {
      for (Method method : javaClass.getMethods()) {
        if (method.getName().equals(methodName)
            && method.getSignature().equals(symbol.getDescriptor())) {
          if (!isMemberAccessibleFrom(javaClass, method, sourceClassName)) {
            return Optional.of(
                new SymbolProblem(symbol, ErrorType.INACCESSIBLE_MEMBER, containingClassFile));
          }
          // The method is found and accessible. Returning no error.
          return Optional.empty();
        }
      }
    }

    // Slf4J catches LinkageError to check the existence of other classes
    if (classDumper.catchesLinkageErrorOnMethod(sourceClassName)) {
      return Optional.empty();
    }

    // The class is in class path but the symbol is not found
    return Optional.of(
        new SymbolProblem(symbol, ErrorType.SYMBOL_NOT_FOUND, containingClassFile));
  } catch (ClassNotFoundException ex) {
    if (classDumper.catchesLinkageErrorOnClass(sourceClassName)) {
      return Optional.empty();
    }
    ClassSymbol classSymbol = new ClassSymbol(symbol.getClassBinaryName());
    return Optional.of(new SymbolProblem(classSymbol, ErrorType.CLASS_NOT_FOUND, null));
  }
}
 
Example 6
Source File: CloneIdiom.java    From spotbugs with GNU Lesser General Public License v2.1 4 votes vote down vote up
@Override
public void visit(JavaClass obj) {
    implementsCloneableDirectly = false;
    invokesSuperClone = false;
    cloneOnlyThrowsException = false;
    isCloneable = false;
    check = false;
    isFinal = obj.isFinal();
    if (obj.isInterface()) {
        return;
    }
    if (obj.isAbstract()) {
        return;
    }
    // Does this class directly implement Cloneable?
    String[] interface_names = obj.getInterfaceNames();
    for (String interface_name : interface_names) {
        if ("java.lang.Cloneable".equals(interface_name)) {
            implementsCloneableDirectly = true;
            isCloneable = true;
            break;
        }
    }

    Subtypes2 subtypes2 = AnalysisContext.currentAnalysisContext().getSubtypes2();
    try {
        if (subtypes2.isSubtype(getClassDescriptor(), cloneDescriptor)) {
            isCloneable = true;
        }
        if (subtypes2.isSubtype(DescriptorFactory.createClassDescriptorFromDottedClassName(obj.getSuperclassName()),
                cloneDescriptor)) {
            implementsCloneableDirectly = false;
        }

    } catch (ClassNotFoundException e) {
        bugReporter.reportMissingClass(e);
    }

    hasCloneMethod = false;
    referencesCloneMethod = false;
    check = true;
    super.visit(obj);
}
 
Example 7
Source File: FindHEmismatch.java    From spotbugs with GNU Lesser General Public License v2.1 4 votes vote down vote up
private void check(int pos) {
    OpcodeStack.Item item = stack.getStackItem(pos);
    JavaClass type = null;

    try {
        type = item.getJavaClass();
    } catch (ClassNotFoundException e) {
        AnalysisContext.reportMissingClass(e);
    }
    if (type == null) {
        return;
    }
    String typeName = type.getClassName();
    if (typeName.startsWith("java.lang")) {
        return;
    }
    int priority = NORMAL_PRIORITY;

    OpcodeStack.Item collection = stack.getStackItem(PreorderVisitor.getNumberArguments(getSigConstantOperand()));
    String collectionSignature = collection.getSignature();
    if (collectionSignature.indexOf("Tree") >= 0
            || collectionSignature.indexOf("Sorted") >= 0
            || collectionSignature.indexOf("SkipList") >= 0) {
        return;
    }

    if (collectionSignature.indexOf("Hash") >= 0) {
        priority--;
    }
    if (!AnalysisContext.currentAnalysisContext()/* .getSubtypes() */.isApplicationClass(type)) {
        priority++;
    }

    if (type.isAbstract() || type.isInterface()) {
        priority++;
    }
    potentialBugs.put(
            type.getClassName(),
            new BugInstance(this, "HE_USE_OF_UNHASHABLE_CLASS", priority).addClassAndMethod(this)
                    .addTypeOfNamedClass(type.getClassName()).describe(TypeAnnotation.UNHASHABLE_ROLE).addCalledMethod(this)
                    .addSourceLine(this));
}
 
Example 8
Source File: FindHEmismatch.java    From spotbugs with GNU Lesser General Public License v2.1 4 votes vote down vote up
@Override
public void visit(Signature obj) {
    if (!isApplicationClass) {
        return;
    }

    String sig = obj.getSignature();
    String className = findHashedClassInSignature(sig);
    if (className == null) {
        return;
    }
    if (className.startsWith("java.lang")) {
        return;
    }
    JavaClass type = null;

    try {
        type = Repository.lookupClass(className);
    } catch (ClassNotFoundException e) {
        AnalysisContext.reportMissingClass(e);
    }
    if (type == null) {
        return;
    }

    int priority = NORMAL_PRIORITY;
    if (sig.indexOf("Hash") >= 0) {
        priority--;
    }
    if (type.isAbstract() || type.isInterface()) {
        priority++;
    }
    if (!AnalysisContext.currentAnalysisContext()/* .getSubtypes() */.isApplicationClass(type)) {
        priority++;
    }

    BugInstance bug = null;

    if (visitingField()) {
        bug = new BugInstance(this, "HE_SIGNATURE_DECLARES_HASHING_OF_UNHASHABLE_CLASS", priority).addClass(this)
                .addVisitedField(this).addTypeOfNamedClass(className).describe(TypeAnnotation.UNHASHABLE_ROLE);
    } else if (visitingMethod()) {
        bug = new BugInstance(this, "HE_SIGNATURE_DECLARES_HASHING_OF_UNHASHABLE_CLASS", priority).addClassAndMethod(this)
                .addTypeOfNamedClass(className).describe(TypeAnnotation.UNHASHABLE_ROLE);
    } else {
        bug = new BugInstance(this, "HE_SIGNATURE_DECLARES_HASHING_OF_UNHASHABLE_CLASS", priority).addClass(this)
                .addClass(this).addTypeOfNamedClass(className).describe(TypeAnnotation.UNHASHABLE_ROLE);
    }
    potentialBugs.put(className, bug);
}
 
Example 9
Source File: DeepSubtypeAnalysis.java    From spotbugs with GNU Lesser General Public License v2.1 4 votes vote down vote up
public static double isDeepSerializable(JavaClass x) throws ClassNotFoundException {
    if (storedException != null) {
        throw storedException;
    }

    if (Values.DOTTED_JAVA_LANG_OBJECT.equals(x.getClassName())) {
        return 0.4;
    }

    if (DEBUG) {
        System.out.println("checking " + x.getClassName());
    }

    double result = Analyze.deepInstanceOf(x, serializable);
    if (result >= 0.9) {
        if (DEBUG) {
            System.out.println("Direct high serializable result: " + result);
        }
        return result;
    }

    if (x.isFinal()) {
        return result;
    }

    double collectionResult = Analyze.deepInstanceOf(x, collection);
    double mapResult = Analyze.deepInstanceOf(x, map);

    if (x.isInterface() || x.isAbstract()) {
        result = Math.max(result, Math.max(mapResult, collectionResult) * 0.95);
        if (result >= 0.9) {
            return result;
        }
    }
    ClassDescriptor classDescriptor = DescriptorFactory.createClassDescriptor(x);

    Subtypes2 subtypes2 = AnalysisContext.currentAnalysisContext().getSubtypes2();

    Set<ClassDescriptor> directSubtypes = subtypes2.getDirectSubtypes(classDescriptor);
    directSubtypes.remove(classDescriptor);


    double confidence = 0.6;
    if (x.isAbstract() || x.isInterface()) {
        confidence = 0.8;
        result = Math.max(result, 0.4);
    } else if (directSubtypes.isEmpty()) {
        confidence = 0.2;
    }

    double confidence2 = (1 + confidence) / 2;
    result = Math.max(result, confidence2 * collectionResult);
    if (result >= 0.9) {
        if (DEBUG) {
            System.out.println("High collection result: " + result);
        }
        return result;
    }
    result = Math.max(result, confidence2 * mapResult);
    if (result >= 0.9) {
        if (DEBUG) {
            System.out.println("High map result: " + result);
        }
        return result;
    }
    result = Math.max(result, confidence2 * 0.5 * Analyze.deepInstanceOf(x, comparator));
    if (result >= 0.9) {
        if (DEBUG) {
            System.out.println("High comparator result: " + result);
        }
        return result;
    }



    for (ClassDescriptor subtype : directSubtypes) {
        JavaClass subJavaClass = Repository.lookupClass(subtype.getDottedClassName());
        result = Math.max(result, confidence * Analyze.deepInstanceOf(subJavaClass, serializable));

        // result = Math.max(result, confidence * isDeepSerializable(subJavaClass));
        if (result >= 0.9) {
            return result;
        }
    }


    if (DEBUG) {
        System.out.println("No high results; max: " + result);
    }
    return result;
}
 
Example 10
Source File: ClassFilePreDecompilationScan.java    From windup with Eclipse Public License 1.0 4 votes vote down vote up
private void addClassFileMetadata(GraphRewrite event, EvaluationContext context, JavaClassFileModel javaClassFileModel)
{
    try (FileInputStream fis = new FileInputStream(javaClassFileModel.getFilePath()))
    {
        final ClassParser parser = new ClassParser(fis, javaClassFileModel.getFilePath());
        final JavaClass bcelJavaClass = parser.parse();
        final String packageName = bcelJavaClass.getPackageName();

        final String qualifiedName = bcelJavaClass.getClassName();

        final JavaClassService javaClassService = new JavaClassService(event.getGraphContext());
        final JavaClassModel javaClassModel = javaClassService.create(qualifiedName);
        int majorVersion = bcelJavaClass.getMajor();
        int minorVersion = bcelJavaClass.getMinor();

        String simpleName = qualifiedName;
        if (packageName != null && !packageName.isEmpty() && simpleName != null)
        {
            simpleName = StringUtils.substringAfterLast(simpleName, ".");
        }

        javaClassFileModel.setMajorVersion(majorVersion);
        javaClassFileModel.setMinorVersion(minorVersion);
        javaClassFileModel.setPackageName(packageName);

        javaClassModel.setSimpleName(simpleName);
        javaClassModel.setPackageName(packageName);
        javaClassModel.setQualifiedName(qualifiedName);
        javaClassModel.setClassFile(javaClassFileModel);
        javaClassModel.setPublic(bcelJavaClass.isPublic());
        javaClassModel.setInterface(bcelJavaClass.isInterface());

        final String[] interfaceNames = bcelJavaClass.getInterfaceNames();
        if (interfaceNames != null)
        {
            for (final String interfaceName : interfaceNames)
            {
                JavaClassModel interfaceModel = javaClassService.getOrCreatePhantom(interfaceName);
                javaClassService.addInterface(javaClassModel, interfaceModel);
            }
        }

        String superclassName = bcelJavaClass.getSuperclassName();
        if (!bcelJavaClass.isInterface() && !StringUtils.isBlank(superclassName))
            javaClassModel.setExtends(javaClassService.getOrCreatePhantom(superclassName));

        javaClassFileModel.setJavaClass(javaClassModel);
    }
    catch (Exception ex)
    {
        String nl = ex.getMessage() != null ? Util.NL + "\t" : " ";
        final String message = "BCEL was unable to parse class file '" + javaClassFileModel.getFilePath() + "':" + nl + ex.toString();
        LOG.log(Level.WARNING, message);
        ClassificationService classificationService = new ClassificationService(event.getGraphContext());
        classificationService.attachClassification(event, context, javaClassFileModel, UNPARSEABLE_CLASS_CLASSIFICATION, UNPARSEABLE_CLASS_DESCRIPTION);
        javaClassFileModel.setParseError(message);
        javaClassFileModel.setSkipDecompilation(true);
    }
}