google/dagger

Compilation Error in Generated Sources Using JPMS

mikewacker opened this issue · 0 comments

Repro Steps

Here's the outline of a "Hello, world!" example using a Greeter that depends on a RecipientFinder; the greeter says hello to the recipient. The example uses the Java Platform Module System (JPMS).

  1. In module lib, package org.example.lib.internal (not exported): Create an @Inject'able RecipientFinder class.
  2. In module lib, package org.example.lib (exported): Create an @Inject'able Greeter class; its @Inject'ed constructor has a RecipientFinder arg.
  3. In module app: Create a GreeterComponent interface, a @Component that provides a Greeter.

Note: dagger-jpms.zip has a working implementation of this example.

Expected Behavior: This example compiles.

Actual Behavior: This example does not compile. The code for DaggerGreeterComponent in the app module will reference types in org.example.lib.internal, which are not visible since module lib does not export that package.

Generating Code

Without Dagger: I would have a no-arg GreetingFactory.create() method or a static Greeting.create() factory method in the lib module; this method would create the RecipientFinder instance and use it to create a Greeter instance.

With Dagger: DaggerGreetingComponent is what wires everything together. However, since that type is in the app module, it cannot access unexported packages in the lib module.

Context

The real-world context for this was a type whose @Inject'ed constructor depended on both "external" types and "internal" types.

  • The associated @Module would bind all the "internal" types, which existed in packages that were not exported.
  • The consumer of said module would be responsible for binding the "external" types.

Now granted, there is no easy fix for this issue, but it can make Dagger unusable with the JPMS.