Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Compiling with System.getProperty can throw NPE rather than useful error #9885

Open
niloc132 opened this issue Dec 31, 2023 · 1 comment
Open
Assignees
Milestone

Comments

@niloc132
Copy link
Contributor

GWT version: 2.9, 2.10, 2.11
Browser (with version): n/a
Operating System: any


Description

Both binding properties and configuration properties (single value only) can be used to provide strings that can be read at compile time via System.getProperty, but if no value is set on a configuration property, a NPE will occur in the compiler.

Cases that should be supported:

  • Multi-value configuration properties correctly emit an error:
       [ERROR] Errors in 'com/google/gwt/dev/jjs/test/SystemGetPropertyTest.java'
          [ERROR] Line 42: Property 'someConfigProperty' is multivalued. Multivalued properties are not supported by System.getProperty().
    
  • No property defined in .gwt.xml, either binding or configuration results in default value being used (if provided), otherwise error:
       [ERROR] Errors in 'com/google/gwt/dev/jjs/test/SystemGetPropertyTest.java'
          [ERROR] Line 45: Property 'unknownProperty' is not defined.
    
  • Configuration properties defined without a value however result in an NPE:
       Compiling 1 permutation
          [ERROR] An internal compiler exception occurred
    com.google.gwt.dev.jjs.InternalCompilerException: Unexpected error during visit.
        at com.google.gwt.dev.jjs.ast.JVisitor.translateException(JVisitor.java:111)
        at com.google.gwt.dev.jjs.ast.JModVisitor.acceptImmutable(JModVisitor.java:313)
        at com.google.gwt.dev.jjs.ast.JMethodCall.visitChildren(JMethodCall.java:275)
        at com.google.gwt.dev.jjs.ast.JMethodCall.traverse(JMethodCall.java:266)
        at com.google.gwt.dev.jjs.ast.JModVisitor.traverse(JModVisitor.java:361)
        at com.google.gwt.dev.jjs.ast.JModVisitor.accept(JModVisitor.java:273)
        at com.google.gwt.dev.jjs.ast.JModVisitor.accept(JModVisitor.java:265)
        at com.google.gwt.dev.jjs.ast.JVisitor.accept(JVisitor.java:118)
        at com.google.gwt.dev.jjs.ast.JExpressionStatement.traverse(JExpressionStatement.java:42)
        at com.google.gwt.dev.jjs.ast.JModVisitor$ListContext.traverse(JModVisitor.java:88)
        at com.google.gwt.dev.jjs.ast.JModVisitor.acceptWithInsertRemove(JModVisitor.java:331)
        at com.google.gwt.dev.jjs.ast.JBlock.traverse(JBlock.java:94)
        at com.google.gwt.dev.jjs.ast.JModVisitor.traverse(JModVisitor.java:361)
        at com.google.gwt.dev.jjs.ast.JModVisitor.accept(JModVisitor.java:273)
        at com.google.gwt.dev.jjs.ast.JVisitor.accept(JVisitor.java:139)
        at com.google.gwt.dev.jjs.ast.JVisitor.accept(JVisitor.java:135)
        at com.google.gwt.dev.jjs.ast.JMethodBody.traverse(JMethodBody.java:83)
        at com.google.gwt.dev.jjs.ast.JModVisitor.traverse(JModVisitor.java:361)
        at com.google.gwt.dev.jjs.ast.JModVisitor.accept(JModVisitor.java:273)
        at com.google.gwt.dev.jjs.ast.JModVisitor.accept(JModVisitor.java:265)
        at com.google.gwt.dev.jjs.ast.JMethod.visitChildren(JMethod.java:786)
        at com.google.gwt.dev.jjs.ast.JMethod.traverse(JMethod.java:778)
        at com.google.gwt.dev.jjs.ast.JModVisitor$ListContextImmutable.traverse(JModVisitor.java:169)
        at com.google.gwt.dev.jjs.ast.JModVisitor.acceptWithInsertRemoveImmutable(JModVisitor.java:336)
        at com.google.gwt.dev.jjs.ast.JClassType.traverse(JClassType.java:147)
        at com.google.gwt.dev.jjs.ast.JModVisitor.traverse(JModVisitor.java:361)
        at com.google.gwt.dev.jjs.ast.JModVisitor.accept(JModVisitor.java:273)
        at com.google.gwt.dev.jjs.ast.JModVisitor.accept(JModVisitor.java:265)
        at com.google.gwt.dev.jjs.ast.JProgram.visitModuleTypes(JProgram.java:1284)
        at com.google.gwt.dev.jjs.ast.JProgram.traverse(JProgram.java:1249)
        at com.google.gwt.dev.jjs.ast.JModVisitor.traverse(JModVisitor.java:361)
        at com.google.gwt.dev.jjs.ast.JModVisitor.accept(JModVisitor.java:273)
        at com.google.gwt.dev.jjs.ast.JModVisitor.accept(JModVisitor.java:265)
        at com.google.gwt.dev.jjs.impl.ResolvePermutationDependentValues.execImpl(ResolvePermutationDependentValues.java:163)
        at com.google.gwt.dev.jjs.impl.ResolvePermutationDependentValues.exec(ResolvePermutationDependentValues.java:113)
        at com.google.gwt.dev.jjs.JavaToJavaScriptCompiler.compilePermutation(JavaToJavaScriptCompiler.java:333)
        at com.google.gwt.dev.jjs.JavaToJavaScriptCompiler.compilePermutation(JavaToJavaScriptCompiler.java:272)
        at com.google.gwt.dev.CompilePerms.compile(CompilePerms.java:198)
        at com.google.gwt.dev.ThreadedPermutationWorkerFactory$ThreadedPermutationWorker.compile(ThreadedPermutationWorkerFactory.java:50)
        at com.google.gwt.dev.PermutationWorkerFactory$Manager$WorkerThread.run(PermutationWorkerFactory.java:74)
        at java.base/java.lang.Thread.run(Thread.java:829)
    Caused by: java.lang.NullPointerException
        at com.google.gwt.thirdparty.guava.common.base.Preconditions.checkNotNull(Preconditions.java:212)
        at com.google.gwt.thirdparty.guava.common.base.Joiner.toString(Joiner.java:447)
        at com.google.gwt.thirdparty.guava.common.base.Joiner.appendTo(Joiner.java:110)
        at com.google.gwt.thirdparty.guava.common.base.Joiner.appendTo(Joiner.java:154)
        at com.google.gwt.thirdparty.guava.common.base.Joiner.join(Joiner.java:197)
        at com.google.gwt.thirdparty.guava.common.base.Joiner.join(Joiner.java:186)
        at com.google.gwt.dev.jjs.impl.ResolvePermutationDependentValues$ValueReplacer.propertyValueExpression(ResolvePermutationDependentValues.java:79)
        at com.google.gwt.dev.jjs.impl.ResolvePermutationDependentValues$ValueReplacer.endVisit(ResolvePermutationDependentValues.java:73)
        at com.google.gwt.dev.jjs.ast.JPermutationDependentValue.traverse(JPermutationDependentValue.java:112)
        at com.google.gwt.dev.jjs.ast.JModVisitor.traverse(JModVisitor.java:361)
        at com.google.gwt.dev.jjs.ast.JModVisitor.acceptImmutable(JModVisitor.java:305)
        ... 39 more
             [ERROR] at SystemGetPropertyTest.java(44): System.getProperty("someConfigPropertyUnset", "bar")
             [ERROR] at SystemGetPropertyTest.java(44): Assert.assertEquals("bar", System.getProperty("someConfigPropertyUnset", "bar"))
             [ERROR] at SystemGetPropertyTest.java(44): Assert.assertEquals("bar", System.getProperty("someConfigPropertyUnset", "bar"))
             [ERROR] at SystemGetPropertyTest.java(41): {
      Assert.assertEquals("foo", "foo");
      Assert.assertEquals("foo", "foo");
      Assert.assertEquals("bar", System.getProperty("someConfigPropertyUnset", "bar"));
    }
             [ERROR] at SystemGetPropertyTest.java(41): {
      Assert.assertEquals("foo", "foo");
      Assert.assertEquals("foo", "foo");
      Assert.assertEquals("bar", System.getProperty("someConfigPropertyUnset", "bar"));
    }
             [ERROR] at SystemGetPropertyTest.java(41): com.google.gwt.dev.jjs.test.SystemGetPropertyTest.testConfigurationProperties()V
             [ERROR] at SystemGetPropertyTest.java(23): com.google.gwt.dev.jjs.test.SystemGetPropertyTest (extends GWTTestCase)
             [ERROR] at Unknown(0): <JProgram>
          [ERROR] Unrecoverable exception, shutting down
    
Steps to reproduce

Declare a configuration property, but don't assign it (for example, one .gwt.xml for a library might declare it, and a downstream app may choose to set it):

  <define-configuration-property name="someConfigPropertyUnset" is-multi-valued="false"/>

Attempt to use that property in GWT/Java sources without a default:

    assertEquals("bar", System.getProperty("someConfigPropertyUnset", "bar"));

Expected: default value is used
Actual: NPE is thrown during compilation

Known workarounds

The simplest workaround is to just define a "this is unset" value for the configuration property, but that means that shared code has two places to change the default.

  <set-configuration-property name="someConfigPropertyUnset" value="this-is-unset" />
@niloc132 niloc132 added this to the 2.12 milestone Dec 31, 2023
@niloc132 niloc132 self-assigned this Dec 31, 2023
@niloc132
Copy link
Contributor Author

Also related to #9806 and #9807 I believe.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant