Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Error parsing signature of lambda #140

Closed
barney2k7 opened this issue Dec 1, 2016 · 8 comments
Closed

Error parsing signature of lambda #140

barney2k7 opened this issue Dec 1, 2016 · 8 comments

Comments

@barney2k7
Copy link

This is a followup to https://sourceforge.net/p/findbugs/bugs/1415/
I tried if the error still occurs with findbugs 3.1.0_preview2 that contains a newer bcel - it still occurs, but now with a different error message.

Steps to reproduce:
1.) compile the following code using Eclipse 4.6

public interface HasUniqueKey<Key> {
  Key getInternId();
}

public class Util {
  public static List<Integer> toIntegerList(List<? extends HasUniqueKey<Integer>> entities) {
    return entities.stream().map(m -> m.getInternId()).collect(Collectors.toList());
  }
}

Note that compiling the code with javac will NOT show the problem, as javac produces quite different byte code when compiling the lambda.

2.) let findbugs analyse the resulting class files (e.g. through the gui). This results in the following stacktrace:

The following errors occurred during analysis:
  Error parsing signature !+LHasUniqueKey<Ljava/lang/Integer;>;
    java.lang.IllegalStateException: Invalid method signature: '(!+LHasUniqueKey<Ljava/lang/Integer;>;)V' : !+LHasUniqueKey<Ljava/lang/Integer;>;)V 
      At edu.umd.cs.findbugs.ba.generic.GenericSignatureParser$ParameterSignatureIterator.next(GenericSignatureParser.java:120)
      At edu.umd.cs.findbugs.ba.generic.GenericSignatureParser$ParameterSignatureIterator.next(GenericSignatureParser.java:45)
      At edu.umd.cs.findbugs.ba.generic.GenericSignatureParser.getNumParameters(GenericSignatureParser.java:184)
      At edu.umd.cs.findbugs.ba.generic.GenericUtilities.getType(GenericUtilities.java:263)
      At edu.umd.cs.findbugs.ba.type.TypeFrameModelingVisitor.getLocalVariable(TypeFrameModelingVisitor.java:827)
      At edu.umd.cs.findbugs.ba.type.TypeFrameModelingVisitor.handleLoadInstruction(TypeFrameModelingVisitor.java:889)
      At edu.umd.cs.findbugs.ba.AbstractFrameModelingVisitor.visitALOAD(AbstractFrameModelingVisitor.java:452)
      At org.apache.bcel.generic.ALOAD.accept(ALOAD.java:56)
      At edu.umd.cs.findbugs.ba.AbstractFrameModelingVisitor.analyzeInstruction(AbstractFrameModelingVisitor.java:84)
      At edu.umd.cs.findbugs.ba.type.TypeFrameModelingVisitor.analyzeInstruction(TypeFrameModelingVisitor.java:197)
      At edu.umd.cs.findbugs.ba.type.TypeAnalysis.transferInstruction(TypeAnalysis.java:406)
      At edu.umd.cs.findbugs.ba.type.TypeAnalysis.transferInstruction(TypeAnalysis.java:86)
      At edu.umd.cs.findbugs.ba.AbstractDataflowAnalysis.transfer(AbstractDataflowAnalysis.java:135)
      At edu.umd.cs.findbugs.ba.type.TypeAnalysis.transfer(TypeAnalysis.java:414)
      At edu.umd.cs.findbugs.ba.type.TypeAnalysis.transfer(TypeAnalysis.java:86)
      At edu.umd.cs.findbugs.ba.Dataflow.execute(Dataflow.java:376)
      At edu.umd.cs.findbugs.classfile.engine.bcel.TypeDataflowFactory.analyze(TypeDataflowFactory.java:83)
      At edu.umd.cs.findbugs.classfile.engine.bcel.TypeDataflowFactory.analyze(TypeDataflowFactory.java:43)
      At edu.umd.cs.findbugs.classfile.impl.AnalysisCache.analyzeMethod(AnalysisCache.java:369)
      At edu.umd.cs.findbugs.classfile.impl.AnalysisCache.getMethodAnalysis(AnalysisCache.java:322)
      At edu.umd.cs.findbugs.classfile.engine.bcel.CFGFactory.analyze(CFGFactory.java:160)
      At edu.umd.cs.findbugs.classfile.engine.bcel.CFGFactory.analyze(CFGFactory.java:65)
      At edu.umd.cs.findbugs.classfile.impl.AnalysisCache.analyzeMethod(AnalysisCache.java:369)
      At edu.umd.cs.findbugs.classfile.impl.AnalysisCache.getMethodAnalysis(AnalysisCache.java:322)
      At edu.umd.cs.findbugs.ba.ClassContext.getMethodAnalysis(ClassContext.java:1005)
      At edu.umd.cs.findbugs.ba.ClassContext.getMethodAnalysisNoDataflowAnalysisException(ClassContext.java:990)
      At edu.umd.cs.findbugs.ba.ClassContext.getCFG(ClassContext.java:303)
      At edu.umd.cs.findbugs.detect.BuildNonnullReturnDatabase.analyzeMethod(BuildNonnullReturnDatabase.java:87)
      At edu.umd.cs.findbugs.detect.BuildNonnullReturnDatabase.considerMethod(BuildNonnullReturnDatabase.java:76)
      At edu.umd.cs.findbugs.detect.BuildNonnullReturnDatabase.visitClassContext(BuildNonnullReturnDatabase.java:67)
      At edu.umd.cs.findbugs.DetectorToDetector2Adapter.visitClass(DetectorToDetector2Adapter.java:76)
      At edu.umd.cs.findbugs.FindBugs2.analyzeApplication(FindBugs2.java:1089)
      At edu.umd.cs.findbugs.FindBugs2.execute(FindBugs2.java:283)
      At edu.umd.cs.findbugs.gui2.BugLoader.doAnalysis(BugLoader.java:101)
      At edu.umd.cs.findbugs.gui2.AnalyzingDialog$AnalysisThread.run(AnalyzingDialog.java:275)
  Error parsing signature !+LHasUniqueKey<Ljava/lang/Integer;>;
    java.lang.IllegalStateException: Invalid method signature: '(!+LHasUniqueKey<Ljava/lang/Integer;>;)V' : !+LHasUniqueKey<Ljava/lang/Integer;>;)V 
      At edu.umd.cs.findbugs.ba.generic.GenericSignatureParser$ParameterSignatureIterator.next(GenericSignatureParser.java:120)
      At edu.umd.cs.findbugs.ba.generic.GenericSignatureParser$ParameterSignatureIterator.next(GenericSignatureParser.java:45)
      At edu.umd.cs.findbugs.ba.generic.GenericSignatureParser.getNumParameters(GenericSignatureParser.java:184)
      At edu.umd.cs.findbugs.ba.generic.GenericUtilities.getType(GenericUtilities.java:263)
      At edu.umd.cs.findbugs.ba.type.TypeFrameModelingVisitor.getLocalVariable(TypeFrameModelingVisitor.java:827)
      At edu.umd.cs.findbugs.ba.type.TypeFrameModelingVisitor.handleLoadInstruction(TypeFrameModelingVisitor.java:889)
      At edu.umd.cs.findbugs.ba.AbstractFrameModelingVisitor.visitALOAD(AbstractFrameModelingVisitor.java:452)
      At org.apache.bcel.generic.ALOAD.accept(ALOAD.java:56)
      At edu.umd.cs.findbugs.ba.AbstractFrameModelingVisitor.analyzeInstruction(AbstractFrameModelingVisitor.java:84)
      At edu.umd.cs.findbugs.ba.type.TypeFrameModelingVisitor.analyzeInstruction(TypeFrameModelingVisitor.java:197)
      At edu.umd.cs.findbugs.ba.type.TypeAnalysis.transferInstruction(TypeAnalysis.java:406)
      At edu.umd.cs.findbugs.ba.type.TypeAnalysis.transferInstruction(TypeAnalysis.java:86)
      At edu.umd.cs.findbugs.ba.AbstractDataflowAnalysis.transfer(AbstractDataflowAnalysis.java:135)
      At edu.umd.cs.findbugs.ba.type.TypeAnalysis.transfer(TypeAnalysis.java:414)
      At edu.umd.cs.findbugs.ba.type.TypeAnalysis.transfer(TypeAnalysis.java:86)
      At edu.umd.cs.findbugs.ba.Dataflow.execute(Dataflow.java:376)
      At edu.umd.cs.findbugs.detect.FindRefComparison.analyzeMethod(FindRefComparison.java:769)
      At edu.umd.cs.findbugs.detect.FindRefComparison.visitClassContext(FindRefComparison.java:696)
      At edu.umd.cs.findbugs.DetectorToDetector2Adapter.visitClass(DetectorToDetector2Adapter.java:76)
      At edu.umd.cs.findbugs.FindBugs2.analyzeApplication(FindBugs2.java:1089)
      At edu.umd.cs.findbugs.FindBugs2.execute(FindBugs2.java:283)
      At edu.umd.cs.findbugs.gui2.BugLoader.doAnalysis(BugLoader.java:101)
      At edu.umd.cs.findbugs.gui2.AnalyzingDialog$AnalysisThread.run(AnalyzingDialog.java:275)

@jsotuyod
Copy link
Contributor

jsotuyod commented Dec 1, 2016

Hi @barney2k7! You may not know this, but FindBugs is dead. Many members of the community forked it and are working on it's successor, SpotBugs, where we are working on a 3.1.0 release with proper Java 8 and Java 9 support.

I'd love to look into this as part of that effort. Could you please provide a .class showing this issue? Thanks in advanced.

P.S. Feel free to report any other issues you find directly on our issues pages

@barney2k7
Copy link
Author

There seems to be quite a disagreement whether FindBugs is dead or not - anyway, I'm glad there's a future for FindBugs one way or another.

The two classes in my 'steps to reproduce' show the issue. All you need to do is compiling them with Eclipse 4.6. Here they are as .class: findbugs_issue_140_compiled.zip

Is there a release of SpotBugs available (or at least a snapshot)? I'll gladly test it in our environment and submit bugs. I've submitted #141 yesterday which I assume affects SpotBugs as well, but I'd like to actually test it with SpotBugs before submitting it to your issues page.

@jsotuyod
Copy link
Contributor

jsotuyod commented Dec 2, 2016

Thanks a lot for the compiled classes. I was able to reproduce it on Eclipse Neon too.

javap -c -s -l -v -p -constants shows the lambda is compiled as:

  private static java.lang.Integer lambda$0(HasUniqueKey);
    descriptor: (LHasUniqueKey;)Ljava/lang/Integer;
    flags: ACC_PRIVATE, ACC_STATIC, ACC_SYNTHETIC
    Code:
      stack=1, locals=1, args_size=1
         0: aload_0
         1: invokeinterface #68,  1           // InterfaceMethod HasUniqueKey.getInternId:()Ljava/lang/Object;
         6: checkcast     #74                 // class java/lang/Integer
         9: areturn
      LineNumberTable:
        line 8: 0
      LocalVariableTable:
        Start  Length  Slot  Name   Signature
            0      10     0     m   LHasUniqueKey;
      LocalVariableTypeTable:
        Start  Length  Slot  Name   Signature
            0      10     0     m   !+LHasUniqueKey<Ljava/lang/Integer;>;

This last signature, !+LHasUniqueKey<Ljava/lang/Integer;>; seems to indeed be invalid according to the JSL definition of signatures. It's still running since LocalVariableTypeTable is metadata used only for debuggers, and java won't read it on normal execution. FindBugs however, will look at it if available to obtain info on generics.

I'll keep on researching this since I'm probably missing something, but so far it looks like a bug on Eclipse JDT. On our side, it seems the most we can do is not blow up if the signature is invalid.

As for FindBugs current status... we did saw that post from Bill. He asked for a week, it's been 25 days. We are yet to hear from him anywhere outside Hacker News (he didn't care to respond on the mailing list, nor show up on Github or SourceForge), so I fear that is not gonna happen. We rather push SpotBugs forward than keep waiting for him.

@jsotuyod
Copy link
Contributor

jsotuyod commented Dec 2, 2016

Confirmed to be an Eclipse issue

Technically, they claim this is due to a void in the JSL which I'm not sure actually exists; non the less, they agree they should probably stop producing signatures outside the spec.

jsotuyod added a commit to spotbugs/spotbugs that referenced this issue Dec 2, 2016
jsotuyod added a commit to spotbugs/spotbugs that referenced this issue Dec 2, 2016
jsotuyod added a commit to spotbugs/spotbugs that referenced this issue Dec 2, 2016
@jsotuyod
Copy link
Contributor

jsotuyod commented Dec 2, 2016

I've jut submitted a PR for SpotBugs to resolve this issue. It will be released as part of SpotBugs 3.1.0

@mebigfatguy
Copy link
Contributor

mebigfatguy commented Dec 2, 2016

the latest bcel should handle this - i think

@jsotuyod
Copy link
Contributor

jsotuyod commented Dec 2, 2016

@mebigfatguy this isn't on BCEL's side, it's on FindBugs when parsing the utf-8 string from the constant pool to obtain generics info from signature. This happens with BCEL 6.0 on SpotBugs HEAD.

BCEL does not (and should not) tamper with the data read from the class file.

mebigfatguy pushed a commit to spotbugs/spotbugs that referenced this issue Dec 3, 2016
* Workaround for JDT illegal signatures

 - See https://bugs.eclipse.org/bugs/show_bug.cgi?id=494198
 - The issue was raised on FindBugs findbugsproject/findbugs#140

* Add more and beter tests for JDT signatures

 - Cover all 3 possibilities
 - Fix an issue with GenericUtilities
 - Take the chance to unify 2 different tests classes on the same parser
@iloveeclipse
Copy link
Member

This project continues development in a new home: https://github.com/spotbugs/spotbugs/

Please do not open new issues here anymore!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants