matthiasblaesing commented on code in PR #6596:
URL: https://github.com/apache/netbeans/pull/6596#discussion_r1367845962


##########
enterprise/glassfish.common/src/org/netbeans/modules/glassfish/common/GlassfishInstanceProvider.java:
##########
@@ -71,17 +83,17 @@ public final class GlassfishInstanceProvider implements 
ServerInstanceProvider,
     public static final String JAKARTAEE10_DEPLOYER_FRAGMENT = 
"deployer:gfv700ee10";
     public static final String EE6WC_DEPLOYER_FRAGMENT = "deployer:gfv3ee6wc"; 
// NOI18N
     public static final String PRELUDE_DEPLOYER_FRAGMENT = "deployer:gfv3"; // 
NOI18N
-    private static String EE6_INSTANCES_PATH = "/GlassFishEE6/Instances"; // 
NOI18N
-    private static String EE7_INSTANCES_PATH = "/GlassFishEE7/Instances"; // 
NOI18N
-    private static String EE8_INSTANCES_PATH = "/GlassFishEE8/Instances"; // 
NOI18N
-    private static String JAKARTAEE8_INSTANCES_PATH = 
"/GlassFishJakartaEE8/Instances"; // NOI18N
-    private static String JAKARTAEE9_INSTANCES_PATH = 
"/GlassFishJakartaEE9/Instances"; // NOI18N
-    private static String JAKARTAEE91_INSTANCES_PATH = 
"/GlassFishJakartaEE91/Instances"; // NOI18N
-    private static String JAKARTAEE10_INSTANCES_PATH = 
"/GlassFishJakartaEE10/Instances"; // NOI18N
-    private static String EE6WC_INSTANCES_PATH = "/GlassFishEE6WC/Instances"; 
// NOI18N
-
-    public static String PRELUDE_DEFAULT_NAME = "GlassFish_v3_Prelude"; 
//NOI18N
-    public static String EE6WC_DEFAULT_NAME = "GlassFish_Server_3.1"; // NOI18N
+    private static final String EE6_INSTANCES_PATH = 
"/GlassFishEE6/Instances"; // NOI18N
+    private static final String EE7_INSTANCES_PATH = 
"/GlassFishEE7/Instances"; // NOI18N
+    private static final String EE8_INSTANCES_PATH = 
"/GlassFishEE8/Instances"; // NOI18N
+    private static final String JAKARTAEE8_INSTANCES_PATH = 
"/GlassFishJakartaEE8/Instances"; // NOI18N
+    private static final String JAKARTAEE9_INSTANCES_PATH = 
"/GlassFishJakartaEE9/Instances"; // NOI18N
+    private static final String JAKARTAEE91_INSTANCES_PATH = 
"/GlassFishJakartaEE91/Instances"; // NOI18N
+    private static final String JAKARTAEE10_INSTANCES_PATH = 
"/GlassFishJakartaEE10/Instances"; // NOI18N
+    private static final String EE6WC_INSTANCES_PATH = 
"/GlassFishEE6WC/Instances"; // NOI18N
+
+    public static final String PRELUDE_DEFAULT_NAME = "GlassFish_v3_Prelude"; 
//NOI18N
+    public static final String EE6WC_DEFAULT_NAME = "GlassFish_Server_3.1"; // 
NOI18N

Review Comment:
   The problem is the "final static". It took me some digging to find the 
specificiation basis and not just some random note, but this builds it: 
   
   https://docs.oracle.com/javase/specs/jls/se8/html/jls-4.html#jls-4.12.4:
   
   > A constant variable is a final variable of primitive type or type String 
that is initialized with a constant expression 
([§15.28](https://docs.oracle.com/javase/specs/jls/se8/html/jls-15.html#jls-15.28)).
 Whether a variable is a constant variable or not may have implications with 
respect to class initialization 
([§12.4.1](https://docs.oracle.com/javase/specs/jls/se8/html/jls-12.html#jls-12.4.1)),
 binary compatibility 
([§13.1](https://docs.oracle.com/javase/specs/jls/se8/html/jls-13.html#jls-13.1),
 
[§13.4.9](https://docs.oracle.com/javase/specs/jls/se8/html/jls-13.html#jls-13.4.9)),
 and definite assignment ([§16 (Definite 
Assignment)](https://docs.oracle.com/javase/specs/jls/se8/html/jls-16.html)).
   
   https://docs.oracle.com/javase/specs/jls/se8/html/jls-13.html#jls-13.1 
(section 3)
   
   > A reference to a field that is a constant variable 
([§4.12.4](https://docs.oracle.com/javase/specs/jls/se8/html/jls-4.html#jls-4.12.4))
 must be resolved at compile time to the value V denoted by the constant 
variable's initializer.
   >
   > If such a field is static, then no reference to the field should be 
present in the code in a binary file, including the class or interface which 
declared the field. Such a field must always appear to have been initialized 
([§12.4.2](https://docs.oracle.com/javase/specs/jls/se8/html/jls-12.html#jls-12.4.2));
 the default initial value for the field (if different than V) must never be 
observed.
   
   You can observe this with this project: 
[constant_variable.zip](https://github.com/apache/netbeans/files/13062491/constant_variable.zip)
   
   Unzip and run from the base directory:
   
   ```
   mvn clean process-classes; javap -v -p 
target/classes/eu/doppelhelix/dev/constantvariable/UseSite.class
   ```
   
   You see, that the string is evaluated at compile time. The string is loaded 
from the constant table (ldc call) an directly passed to `println` from 
`System.out`. The output was created by OpenJDK 17 as shipped with Ubuntu, it 
might be different in your case.
   
   ```
     public static void main(java.lang.String[]);
       descriptor: ([Ljava/lang/String;)V
       flags: (0x0009) ACC_PUBLIC, ACC_STATIC
       Code:
         stack=2, locals=1, args_size=1
            0: getstatic     #7                  // Field 
java/lang/System.out:Ljava/io/PrintStream;
            3: ldc           #15                 // String Hello World!
            5: invokevirtual #17                 // Method 
java/io/PrintStream.println:(Ljava/lang/String;)V
            8: return
         LineNumberTable:
           line 7: 0
           line 8: 8
         LocalVariableTable:
           Start  Length  Slot  Name   Signature
               0       9     0  args   [Ljava/lang/String;
   ```
   
   Now open `ConstantProvider.java`, comment out "Variant 1" and choose one of 
the other variants, repeat.
   
   This yields a much more complex result:
   
   ```
     public static void main(java.lang.String[]);
       descriptor: ([Ljava/lang/String;)V
       flags: (0x0009) ACC_PUBLIC, ACC_STATIC
       Code:
         stack=2, locals=1, args_size=1
            0: getstatic     #7                  // Field 
java/lang/System.out:Ljava/io/PrintStream;
            3: getstatic     #13                 // Field 
eu/doppelhelix/dev/constantvariable/ConstantProvider.WORLD:Ljava/lang/String;
            6: invokedynamic #19,  0             // InvokeDynamic 
#0:makeConcatWithConstants:(Ljava/lang/String;)Ljava/lang/String;
           11: invokevirtual #23                 // Method 
java/io/PrintStream.println:(Ljava/lang/String;)V
           14: return
         LineNumberTable:
           line 7: 0
           line 8: 14
         LocalVariableTable:
           Start  Length  Slot  Name   Signature
               0      15     0  args   [Ljava/lang/String;
   }
   SourceFile: "UseSite.java"
   BootstrapMethods:
     0: #43 REF_invokeStatic 
java/lang/invoke/StringConcatFactory.makeConcatWithConstants:(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;Ljava/lang/String;[Ljava/lang/Object;)Ljava/lang/invoke/CallSite;
       Method arguments:
         #49 Hello \u0001!
   InnerClasses:
     public static final #56= #52 of #54;    // Lookup=class 
java/lang/invoke/MethodHandles$Lookup of class java/lang/invoke/MethodHandles
   ```
   
   Now the value of `ConstantProvider.WORLD` is loaded first (`get static #13`) 
and then passed to the invoke dynamic, that then builds the string at runtime.
   
   TL;DR version: Move initialization into a static initializer block and the 
variables can become final, which being inlined.



##########
enterprise/glassfish.common/src/org/netbeans/modules/glassfish/common/GlassfishInstanceProvider.java:
##########
@@ -71,17 +83,17 @@ public final class GlassfishInstanceProvider implements 
ServerInstanceProvider,
     public static final String JAKARTAEE10_DEPLOYER_FRAGMENT = 
"deployer:gfv700ee10";
     public static final String EE6WC_DEPLOYER_FRAGMENT = "deployer:gfv3ee6wc"; 
// NOI18N
     public static final String PRELUDE_DEPLOYER_FRAGMENT = "deployer:gfv3"; // 
NOI18N
-    private static String EE6_INSTANCES_PATH = "/GlassFishEE6/Instances"; // 
NOI18N
-    private static String EE7_INSTANCES_PATH = "/GlassFishEE7/Instances"; // 
NOI18N
-    private static String EE8_INSTANCES_PATH = "/GlassFishEE8/Instances"; // 
NOI18N
-    private static String JAKARTAEE8_INSTANCES_PATH = 
"/GlassFishJakartaEE8/Instances"; // NOI18N
-    private static String JAKARTAEE9_INSTANCES_PATH = 
"/GlassFishJakartaEE9/Instances"; // NOI18N
-    private static String JAKARTAEE91_INSTANCES_PATH = 
"/GlassFishJakartaEE91/Instances"; // NOI18N
-    private static String JAKARTAEE10_INSTANCES_PATH = 
"/GlassFishJakartaEE10/Instances"; // NOI18N
-    private static String EE6WC_INSTANCES_PATH = "/GlassFishEE6WC/Instances"; 
// NOI18N
-
-    public static String PRELUDE_DEFAULT_NAME = "GlassFish_v3_Prelude"; 
//NOI18N
-    public static String EE6WC_DEFAULT_NAME = "GlassFish_Server_3.1"; // NOI18N
+    private static final String EE6_INSTANCES_PATH = 
"/GlassFishEE6/Instances"; // NOI18N
+    private static final String EE7_INSTANCES_PATH = 
"/GlassFishEE7/Instances"; // NOI18N
+    private static final String EE8_INSTANCES_PATH = 
"/GlassFishEE8/Instances"; // NOI18N
+    private static final String JAKARTAEE8_INSTANCES_PATH = 
"/GlassFishJakartaEE8/Instances"; // NOI18N
+    private static final String JAKARTAEE9_INSTANCES_PATH = 
"/GlassFishJakartaEE9/Instances"; // NOI18N
+    private static final String JAKARTAEE91_INSTANCES_PATH = 
"/GlassFishJakartaEE91/Instances"; // NOI18N
+    private static final String JAKARTAEE10_INSTANCES_PATH = 
"/GlassFishJakartaEE10/Instances"; // NOI18N
+    private static final String EE6WC_INSTANCES_PATH = 
"/GlassFishEE6WC/Instances"; // NOI18N
+
+    public static final String PRELUDE_DEFAULT_NAME = "GlassFish_v3_Prelude"; 
//NOI18N
+    public static final String EE6WC_DEFAULT_NAME = "GlassFish_Server_3.1"; // 
NOI18N

Review Comment:
   The problem is the "final static". It took me some digging to find the 
specificiation basis and not just some random note, but this builds it: 
   
   https://docs.oracle.com/javase/specs/jls/se8/html/jls-4.html#jls-4.12.4:
   
   > A constant variable is a final variable of primitive type or type String 
that is initialized with a constant expression 
([§15.28](https://docs.oracle.com/javase/specs/jls/se8/html/jls-15.html#jls-15.28)).
 Whether a variable is a constant variable or not may have implications with 
respect to class initialization 
([§12.4.1](https://docs.oracle.com/javase/specs/jls/se8/html/jls-12.html#jls-12.4.1)),
 binary compatibility 
([§13.1](https://docs.oracle.com/javase/specs/jls/se8/html/jls-13.html#jls-13.1),
 
[§13.4.9](https://docs.oracle.com/javase/specs/jls/se8/html/jls-13.html#jls-13.4.9)),
 and definite assignment ([§16 (Definite 
Assignment)](https://docs.oracle.com/javase/specs/jls/se8/html/jls-16.html)).
   
   https://docs.oracle.com/javase/specs/jls/se8/html/jls-13.html#jls-13.1 
(section 3)
   
   > A reference to a field that is a constant variable 
([§4.12.4](https://docs.oracle.com/javase/specs/jls/se8/html/jls-4.html#jls-4.12.4))
 must be resolved at compile time to the value V denoted by the constant 
variable's initializer.
   >
   > If such a field is static, then no reference to the field should be 
present in the code in a binary file, including the class or interface which 
declared the field. Such a field must always appear to have been initialized 
([§12.4.2](https://docs.oracle.com/javase/specs/jls/se8/html/jls-12.html#jls-12.4.2));
 the default initial value for the field (if different than V) must never be 
observed.
   
   You can observe this with this project: 
[constant_variable.zip](https://github.com/apache/netbeans/files/13062491/constant_variable.zip)
   
   Unzip and run from the base directory:
   
   ```
   mvn clean process-classes; javap -v -p 
target/classes/eu/doppelhelix/dev/constantvariable/UseSite.class
   ```
   
   You see, that the string is evaluated at compile time. The string is loaded 
from the constant table (ldc call) an directly passed to `println` from 
`System.out`. The output was created by OpenJDK 17 as shipped with Ubuntu, it 
might be different in your case.
   
   ```
     public static void main(java.lang.String[]);
       descriptor: ([Ljava/lang/String;)V
       flags: (0x0009) ACC_PUBLIC, ACC_STATIC
       Code:
         stack=2, locals=1, args_size=1
            0: getstatic     #7                  // Field 
java/lang/System.out:Ljava/io/PrintStream;
            3: ldc           #15                 // String Hello World!
            5: invokevirtual #17                 // Method 
java/io/PrintStream.println:(Ljava/lang/String;)V
            8: return
         LineNumberTable:
           line 7: 0
           line 8: 8
         LocalVariableTable:
           Start  Length  Slot  Name   Signature
               0       9     0  args   [Ljava/lang/String;
   ```
   
   Now open `ConstantProvider.java`, comment out "Variant 1" and choose one of 
the other variants, repeat.
   
   This yields a much more complex result:
   
   ```
     public static void main(java.lang.String[]);
       descriptor: ([Ljava/lang/String;)V
       flags: (0x0009) ACC_PUBLIC, ACC_STATIC
       Code:
         stack=2, locals=1, args_size=1
            0: getstatic     #7                  // Field 
java/lang/System.out:Ljava/io/PrintStream;
            3: getstatic     #13                 // Field 
eu/doppelhelix/dev/constantvariable/ConstantProvider.WORLD:Ljava/lang/String;
            6: invokedynamic #19,  0             // InvokeDynamic 
#0:makeConcatWithConstants:(Ljava/lang/String;)Ljava/lang/String;
           11: invokevirtual #23                 // Method 
java/io/PrintStream.println:(Ljava/lang/String;)V
           14: return
         LineNumberTable:
           line 7: 0
           line 8: 14
         LocalVariableTable:
           Start  Length  Slot  Name   Signature
               0      15     0  args   [Ljava/lang/String;
   }
   SourceFile: "UseSite.java"
   BootstrapMethods:
     0: #43 REF_invokeStatic 
java/lang/invoke/StringConcatFactory.makeConcatWithConstants:(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;Ljava/lang/String;[Ljava/lang/Object;)Ljava/lang/invoke/CallSite;
       Method arguments:
         #49 Hello \u0001!
   InnerClasses:
     public static final #56= #52 of #54;    // Lookup=class 
java/lang/invoke/MethodHandles$Lookup of class java/lang/invoke/MethodHandles
   ```
   
   Now the value of `ConstantProvider.WORLD` is loaded first (`get static #13`) 
and then passed to the invoke dynamic, that then builds the string at runtime.
   
   TL;DR version: Move initialization into a static initializer block and the 
variables can become final, which being inlined.



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

For further information about the NetBeans mailing lists, visit:
https://cwiki.apache.org/confluence/display/NETBEANS/Mailing+lists

Reply via email to