Scalac how disable inline public static int?

I am writing an gradle plugin for compiling android application with scala
I ran into a problem that scalac inlined numeric values of android resources (R.java) to .class-files
At the time of assembly of the android modules, the R values are unknown. Therefore, you need to access them using getstatic.

How can I disable inline public static int which defined in R.class in R.jar?

I don’t really understand. They are static final but they are unknown? When or how are they filled in?
And doesn’t javac also inline static final values? Why on earth do they encode them as compile time constants if they only intend to fill in those values through some runtime reflection magic?

for compile module R.java is

public final class R {
    private R() { }
    public static final class string {
        private string() { }
        public static int app_name;
    }
}

This class is located in module/R.jar

when compile android project R.java

public final class R {
    private R() { }
    public static final class string {
        private string() { }
        public static int app_name = 0x7f0b001b;
    }
}

This class is located in app/R.jar

Thus, when a module is compiled, it refers to the module/R.jar, and when building a project, it must reference app/R.jar

I don’t see a static final int field though. I’m not sure but if scalac treats app_name as a static final constant that might actually be a bug.

I assume you don’t have the optimizer enabled?

Yes, optimizer is disable.

compile options:
0 -> -unchecked
1 -> -encoding
2 -> UTF-8
compiler version:
0 -> 2.11.12
compile order:
0 -> Mixed
name hashing:
0 -> true

If app_name is indeed not final I find it unlikely that it is intended that scalac inlines it. However it’s also rather unlikely that (if it’s actually a bug) this will get fixed in 2.11.

Perhaps you could try setting compile order to JavaThenScala. If that doesn’t work I’m not sure there’s anything you can do. I don’t think you can disable inlining (what the compiler thinks are) compile time constants.

Actually I can’t reproduce this issue.
I see a getstatic in the bytecode:

0: getstatic     #16                 // Field R$string.app_name:I
3: ireturn

Your thoughts gave me an idea. Since a really similar class in the project is compiled into getstatic

The idea is that if scalac public static int compiled to getstatic
and public static final int to iconst_0

Then you should check whether the libraries dependencies have a variant of the type:

public final class R {
    private R() { }
    public static final class string {
        private string() { }
        public static final int app_name = 0;
    }
}

To my regret, the assumption turned out to be false.

I created a small project contains two dependencies R.jar and RM.jar
R.jar is generated from android project
RM.jar contain copy of R.java and compiled as artifact

object Hello extends App {
  println("My compile "+com.kos.sacamodule.R.anim.abc_grow_fade_in_from_bottom+" ok.")
  println("From android "+com.kos.javamodule.R.anim.abc_grow_fade_in_from_bottom+" hm.")
}

it compiled to:

   0: getstatic     #61                 // Field scala/Predef$.MODULE$:Lscala/Predef$;
   3: new           #63                 // class scala/collection/mutable/StringBuilder
   6: dup
   7: invokespecial #64                 // Method scala/collection/mutable/StringBuilder."<init>":()V
  10: ldc           #66                 // String My compile
  12: invokevirtual #70                 // Method scala/collection/mutable/StringBuilder.append:(Ljava/lang/Object;)Lscala/collection/mutable/StringBuilder;
  15: getstatic     #76                 // Field com/kos/sacamodule/R$anim.abc_grow_fade_in_from_bottom:I
  18: invokestatic  #82                 // Method scala/runtime/BoxesRunTime.boxToInteger:(I)Ljava/lang/Integer;
  21: invokevirtual #70                 // Method scala/collection/mutable/StringBuilder.append:(Ljava/lang/Object;)Lscala/collection/mutable/StringBuilder;
  24: ldc           #84                 // String  ok.
  26: invokevirtual #70                 // Method scala/collection/mutable/StringBuilder.append:(Ljava/lang/Object;)Lscala/collection/mutable/StringBuilder;
  29: invokevirtual #88                 // Method scala/collection/mutable/StringBuilder.toString:()Ljava/lang/String;
  32: invokevirtual #92                 // Method scala/Predef$.println:(Ljava/lang/Object;)V
  35: getstatic     #61                 // Field scala/Predef$.MODULE$:Lscala/Predef$;
  38: new           #63                 // class scala/collection/mutable/StringBuilder
  41: dup
  42: invokespecial #64                 // Method scala/collection/mutable/StringBuilder."<init>":()V
  45: ldc           #94                 // String From android
  47: invokevirtual #70                 // Method scala/collection/mutable/StringBuilder.append:(Ljava/lang/Object;)Lscala/collection/mutable/StringBuilder;
  50: iconst_0
  51: invokestatic  #82                 // Method scala/runtime/BoxesRunTime.boxToInteger:(I)Ljava/lang/Integer;
  54: invokevirtual #70                 // Method scala/collection/mutable/StringBuilder.append:(Ljava/lang/Object;)Lscala/collection/mutable/StringBuilder;
  57: ldc           #96                 // String  hm.
  59: invokevirtual #70                 // Method scala/collection/mutable/StringBuilder.append:(Ljava/lang/Object;)Lscala/collection/mutable/StringBuilder;
  62: invokevirtual #88                 // Method scala/collection/mutable/StringBuilder.toString:()Ljava/lang/String;
  65: invokevirtual #92                 // Method scala/Predef$.println:(Ljava/lang/Object;)V
  68: return

This see
15: getstatic - it from my compiled RM.jar

50: iconst_0 - if from android R.jar