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

bug: NPE on duplicate package-info.java when ignoring duplicate types #3790

Closed
slarse opened this issue Feb 9, 2021 · 3 comments · Fixed by #3791
Closed

bug: NPE on duplicate package-info.java when ignoring duplicate types #3790

slarse opened this issue Feb 9, 2021 · 3 comments · Fixed by #3791

Comments

@slarse
Copy link
Collaborator

slarse commented Feb 9, 2021

Spoon and/or JDT is not handling package-info.java files correctly. If multiple of them are found in a single project, there's a duplicate type crash:

Exception in thread "main" spoon.compiler.ModelBuildingException: The type package-info is already defined
	at spoon.support.compiler.jdt.JDTBasedSpoonCompiler.reportProblem(JDTBasedSpoonCompiler.java:600)
	at spoon.support.compiler.jdt.TreeBuilderRequestor.acceptResult(TreeBuilderRequestor.java:29)
	at spoon.support.compiler.jdt.TreeBuilderCompiler.buildUnits(TreeBuilderCompiler.java:87)
	at spoon.support.compiler.jdt.JDTBatchCompiler.getUnits(JDTBatchCompiler.java:256)
	at spoon.support.compiler.jdt.JDTBasedSpoonCompiler.buildUnits(JDTBasedSpoonCompiler.java:417)
	at spoon.support.compiler.jdt.JDTBasedSpoonCompiler.buildUnitsAndModel(JDTBasedSpoonCompiler.java:369)
	at spoon.support.compiler.jdt.JDTBasedSpoonCompiler.buildSources(JDTBasedSpoonCompiler.java:335)
	at spoon.support.compiler.jdt.JDTBasedSpoonCompiler.build(JDTBasedSpoonCompiler.java:116)
	at spoon.support.compiler.jdt.JDTBasedSpoonCompiler.build(JDTBasedSpoonCompiler.java:99)
	at spoon.Launcher.buildModel(Launcher.java:772)
	at Main.main(Main.java:10)

With Environment.setIgnoreDuplicateDeclarations(true), there's an NPE instead.

Exception in thread "main" java.lang.NullPointerException
	at spoon.support.compiler.jdt.JDTTreeBuilder.visit(JDTTreeBuilder.java:1732)
	at org.eclipse.jdt.internal.compiler.ast.TypeDeclaration.traverse(TypeDeclaration.java:1638)
	at org.eclipse.jdt.internal.compiler.ast.CompilationUnitDeclaration.traverse(CompilationUnitDeclaration.java:822)
	at org.eclipse.jdt.internal.compiler.ast.CompilationUnitDeclaration.traverse(CompilationUnitDeclaration.java:783)
	at spoon.support.compiler.jdt.JDTBasedSpoonCompiler.traverseUnitDeclaration(JDTBasedSpoonCompiler.java:480)
	at spoon.support.compiler.jdt.JDTBasedSpoonCompiler.lambda$buildModel$0(JDTBasedSpoonCompiler.java:437)
	at spoon.support.compiler.jdt.JDTBasedSpoonCompiler.forEachCompilationUnit(JDTBasedSpoonCompiler.java:464)
	at spoon.support.compiler.jdt.JDTBasedSpoonCompiler.buildModel(JDTBasedSpoonCompiler.java:435)
	at spoon.support.compiler.jdt.JDTBasedSpoonCompiler.buildUnitsAndModel(JDTBasedSpoonCompiler.java:372)
	at spoon.support.compiler.jdt.JDTBasedSpoonCompiler.buildSources(JDTBasedSpoonCompiler.java:335)
	at spoon.support.compiler.jdt.JDTBasedSpoonCompiler.build(JDTBasedSpoonCompiler.java:116)
	at spoon.support.compiler.jdt.JDTBasedSpoonCompiler.build(JDTBasedSpoonCompiler.java:99)
	at spoon.Launcher.buildModel(Launcher.java:772)
	at Main.main(Main.java:11)

Looking into a fix.

@slarse
Copy link
Collaborator Author

slarse commented Feb 9, 2021

I think the problem is when there are in fact duplicated package-info.java files in the same project. For example, say a multi-module project has the same package in two modules, and have a package-info.java in both of those. JDT does not appear to tolerate that.

So the bug here is probably only that we have an NPE when ignoring duplicates.

@slarse slarse changed the title bug: Crash on multiple package-info.java in a project bug: Crash on duplicate package-info.java when ignoring duplicate types Feb 9, 2021
@slarse
Copy link
Collaborator Author

slarse commented Feb 9, 2021

package-info.java appears to be parsed as an interface by JDT. That seems strange to me. Gotta do some reading here.

@slarse
Copy link
Collaborator Author

slarse commented Feb 9, 2021

Chapter 7.4.1 of the JLS says the following:

At most one annotated package declaration is permitted for a given package.

The manner in which this restriction is enforced must, of necessity, vary from implementation to implementation. The following scheme is strongly recommended for file-system-based implementations: The sole annotated package declaration, if it exists, is placed in a source file called package-info.java in the directory containing the source files for the package. This file does not contain the source for a class called package-info; indeed it would be illegal for it to do so, as package-info is not a legal identifier. Typically package-info.java contains only a package declaration, preceded immediately by the annotations on the package. While the file could technically contain the source code for one or more classes with package access, it would be very bad form.

It is recommended that package-info.java, if it is present, take the place of package.html for javadoc and other similar documentation generation systems. If this file is present, the documentation generation tool should look for the package documentation comment immediately preceding the (possibly annotated) package declaration in package-info.java. [ ... ]

This has been unchanged at least since Java 7.

So, package-info.java simply serves to provide annotations and/or documentation for a single package, and the way I interpret the docs, it is indeed illegal to duplicate this file. Currently, Spoon seems to create an empty compilation unit for each package-info.java. I'm not sure package-info.java actually is a compilation unit, but it seems to mostly work.

Still, I'm pretty confident now that the bug is just the NPE on ignoring duplicate declarations.

@slarse slarse changed the title bug: Crash on duplicate package-info.java when ignoring duplicate types bug: NPE on duplicate package-info.java when ignoring duplicate types Feb 10, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
1 participant