konsoletyper / teavm

Compiles Java bytecode to JavaScript, WebAssembly and C
https://teavm.org
Apache License 2.0
2.65k stars 265 forks source link

Wrong static property values are used #972

Open skerit opened 2 days ago

skerit commented 2 days ago

I've structured a project like this:

server/SpecificBlast.java:

public class SpecificBlast {
    public final static boolean IS_SERVER = true;
}

common/Blast.java:

public class Blast extends SpecificBlast {
    public static void main(String[] args) {
        if (Blast.IS_SERVER) {
            System.out.println("On server");
        } else {
            System.out.println("On browser");
        }
    }
}

browser/TeaSpecificBlast.java:

public class TeaSpecificBlast {
    public final static boolean IS_SERVER = false;
}

And I configured my teavm.properties file like this:

mapPackageHierarchy|be.elevenways.protoblast.browser=be.elevenways.protoblast.server
stripPrefixFromPackageHierarchyClasses|be.elevenways.protoblast.browser=Tea

But whenever I run the generated JavaScript code, it always puts out On server in the console.

When I switch from using static booleans to a static method, like so:

public class SpecificBlast {
    public static boolean isServer() {
        return true;
    }
}

public class Blast extends SpecificBlast {
    public static void main(String[] args) {
        if (Blast.isServer()) {
            System.out.println("On server");
        } else {
            System.out.println("On browser");
        }
    }
}

public class TeaSpecificBlast {
    public static boolean isServer() {
        return false;
    }
}

it does work as expected.

SquidDev commented 2 days ago

The Java compiler will inline constants from static final fields, even across modules. This means that the Blast.main is compiled to if(true) by javac, before TeaVM even sees the classes.

skerit commented 2 days ago

Ah yes, that makes sense. And then TeaVM converts the bytecode to JavaScript.

Is there a more robust alternative to the mapPackageHierarchy solution? Some kind of gradle plugin?

konsoletyper commented 2 days ago

@skerit what do you mean by "more robust"? What's current solution missing in your opinion?