forax / pro

A Java build tool that works seamlessly with modules
GNU General Public License v3.0
103 stars 15 forks source link

Method overloading fails across modules #77

Closed x4e closed 3 years ago

x4e commented 3 years ago

Hello,

I am experiencing an error when attempting to use method overloading across two modules and building with Pro. I have a setup like this:

module first.module {
    requires java.logging;
    exports first.module;
}

package first.module;

import java.util.logging.*;

public class First {
    public static final Logger LOGGER = Logger.getLogger("");
}
module second.module {
    requires first.module;
    exports second.module;
}

package second.module;

import first.module.First;

public class Second {
    public static void main(String[] args) {
        First.LOGGER.info("hello");
    }
}

This fails to build:

src/main/java/second.module/second/module/Second.java:7: error: incompatible types: String cannot be converted to Supplier<String>
                First.LOGGER.info("hello");
                                  ^
Note: Some messages have been simplified; recompile with -Xdiags:verbose to get full output
1 error
[pro] FAILED !        elapsed time 1,343 ms
command 'compiler' exit with code 1

I can fix this by changing the module-info so that second also requires java.logging:

module second.module {
    requires first.module;
    requires java.logging;
    exports second.module;
}

So my questions is whether this is expected behaviour? I am used to Java programming without modules, where you can call methods on classes without importing them as long as you have a reference to them.

Thank You

sormuras commented 3 years ago
javac --module first.module --module-source-path . -Xlint -d classes
.\first.module\First.java:5: warning: [missing-explicit-ctor] class First in exported package first.module declares no explicit constructors, thereby exposing a default constructor to clients of module first.module
public class First {
       ^
.\first.module\First.java:6: warning: [exports] class Logger in module java.logging is not indirectly exported using requires transitive
        public static final Logger LOGGER = Logger.getLogger("");
                            ^
2 warnings

Adding transitive (and and default constructor in First.java) as in:

module first.module {
    requires transitive java.logging;
    exports first.module;
}

eliminates the warnings and makes compiling the module second.module possible.

forax commented 3 years ago

I wonder if there is not also a bug in pro, it may not sandbox correctly it's own logger, Logger in your code may not be java.util.logging.Logger but the logger of pro, using an import without an * may fix the issue.

x4e commented 3 years ago

Thank You @sormuras , that fixed it, this was just me not understanding the module system.

What was really strange to me was how it identified the method I wanted to call, just the wrong one, which suggested that it did have access to java.logging...

And thanks Remi, for now the transitive fixed it but if it happens again I will try that.

sormuras commented 3 years ago

You're welcome.

-Xlint is like a good friend in the modular (compiling) world. It has a lot to say and suggest, if something's not working. 🤓