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] [JSR-199] ECJ cannot resolve JPMS modules if using a user-provided file manager #958

Open
ascopes opened this issue Apr 10, 2023 · 3 comments

Comments

@ascopes
Copy link
Contributor

ascopes commented Apr 10, 2023

It appears that when using ClasspathJSR199 (i.e. when a provided file manager does not implement StandardFileManager, only JavaFileManager), using a module-info.java in the root of the compilation sources does not work correctly. Automatic modules that are mentioned in requires entries are not being added to the module lookup table within the compiler, leading to errors such as the following:

module org.example {
  exports org.example;

  requires io.avaje.inject;  /* automatic module that is a JAR on both the CLASS_PATH and MODULE_PATH */

  provides io.avaje.inject.spi.Module with org.example.ExampleModule;
}
 - [ERROR] 8389908
   
       Cannot bind message for problem (id: 1300) "{0} cannot be resolved to a module" with arguments: {}

 - [ERROR] 16777218
   
       io cannot be resolved to a type

 - [ERROR] 268435846
   
       The import jakarta cannot be resolved

 - [ERROR] 16777218
   
       Singleton cannot be resolved to a type

 - [ERROR] 268435846
   
       The import jakarta cannot be resolved

This appears to be some sort of bug, since I can get the exact same configuration to compile successfully under Javac using the exact same configuration. If I remove the module-info.java from my test project, then this will get past this step, so it seems to be a bug in the module resolution in ECJ somewhere.

ECJ appears to be using a ClasspathJsr199 object if the FileManager is not an instance of EclipseFileManager or StandardFileManager, and my guess is that when using this flow rather than the default file manager the compiler would usually create when invoked as a standalone process, the wrong logic is being invoked to handle JARs that have an Automatic-Module-Name entry in their META-INF/MANIFEST.MF.

Thus, to replicate this, you'll need to use a JavaFileManager object that does not implement EclipseFileManager or StandardFileManager, otherwise this logic appears to be skipped.


Minimal working example (Maven project)

ecj-bugs.tar.gz

./mvnw clean package and observe the failure.

This fails because ECJ doesn't seem to support automatic module detection properly in the ClasspathJsr199 class, and this is only enabled if the StandardJavaFileManager ECJ provides is not used by the looks.

I tricked ECJ into doing this by hiding the regular standard file manager behind one that does not implement StandardJavaFileManager at all.

@ascopes ascopes changed the title ClasspathJSR199 does not resolve automatic module members ECJ fails to resolve Automatic Modules in minimal working example Apr 15, 2023
@ascopes ascopes changed the title ECJ fails to resolve Automatic Modules in minimal working example ECJ fails to resolve any Automatic Modules Apr 15, 2023
@ascopes
Copy link
Contributor Author

ascopes commented Apr 15, 2023

Updated issue with simple working reproduction now. Can confirm it affects the ECJ file manager if you wrap it in a JavaFileManager delegate that doesn't implement StandardJavaFileManager.

@ascopes ascopes changed the title ECJ fails to resolve any Automatic Modules ECJ fails to resolve any modules Apr 30, 2023
@ascopes ascopes changed the title ECJ fails to resolve any modules ECJ cannot resolve modules if using a JavaFileManager Apr 30, 2023
@ascopes
Copy link
Contributor Author

ascopes commented Apr 30, 2023

The issue seems to be that ClasspathJsr199 just delegates to the JRT to find any modules, meaning that a ClasspathJsr199 will never report that it holds modules. Seems the EclipseFileManager deals with this logic in a special way normally, which is not going to be applicable to custom file manager implementations.

Ideally, I would probably expect ClasspathJsr199 to be using the ModuleFinder to find the appropriate modules and automatic modules, or to use the file manager itself with listLocationForModules.

@ascopes ascopes changed the title ECJ cannot resolve modules if using a JavaFileManager [JSR-199] ECJ cannot resolve JPMS modules if using a user-provided file manager Apr 30, 2023
@ascopes ascopes changed the title [JSR-199] ECJ cannot resolve JPMS modules if using a user-provided file manager [BUG] [JSR-199] ECJ cannot resolve JPMS modules if using a user-provided file manager Jun 24, 2023
@ascopes
Copy link
Contributor Author

ascopes commented Jan 4, 2024

Bumping to prevent this being closed from inactivity, as it is still an outstanding issue.

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

1 participant