Uploaded image for project: 'Velocity'
  1. Velocity
  2. VELOCITY-968

In Java 17+, introspection fails in many cases due to permissions

    XMLWordPrintableJSON

Details

    • Bug
    • Status: Resolved
    • Major
    • Resolution: Duplicate
    • 1.7.x, 2.3
    • None
    • Engine
    • None
    • Java 17

    Description

      When running under Java 17 or later, introspection often picks an inaccessible method on a runtime object, which then fails when invoked.

      For example, running the example below under Java 8, the output is simple:

      Cert notAfter=Wed Jan 03 12:42:32 EST 2024
      Test: Wed Jan 03 12:42:32 EST 2024
      

      When running on Java 11 or later, we get:

      Cert notAfter=Wed Jan 03 12:42:32 EST 2024
      WARNING: An illegal reflective access operation has occurred
      WARNING: Illegal reflective access by org.apache.velocity.runtime.parser.node.PropertyExecutor (file:.../velocity-engine-core-2.3.jar) to method sun.security.x509.X509CertImpl.getNotAfter()
      WARNING: Please consider reporting this to the maintainers of org.apache.velocity.runtime.parser.node.PropertyExecutor
      WARNING: Use --illegal-access=warn to enable warnings of further illegal reflective access operations
      WARNING: All illegal access operations will be denied in a future release
      Test: Wed Jan 03 12:42:32 EST 2024
      

      When running on Java 17, we get:

      Cert notAfter=Wed Jan 03 12:42:32 EST 2024
      Exception in thread "main" org.apache.velocity.exception.VelocityException: ASTIdentifier() : exception invoking method for identifier 'notAfter' in class sun.security.x509.X509CertImpl
          at org.apache.velocity.runtime.parser.node.ASTIdentifier.execute(ASTIdentifier.java:282)
          at org.apache.velocity.runtime.parser.node.ASTReference.execute(ASTReference.java:368)
          at org.apache.velocity.runtime.parser.node.ASTReference.render(ASTReference.java:492)
          at org.apache.velocity.runtime.parser.node.SimpleNode.render(SimpleNode.java:439)
          at org.apache.velocity.Template.merge(Template.java:358)
          at org.apache.velocity.Template.merge(Template.java:262)
          at CertTest.main(CertTest.java:52)
      Caused by: java.lang.IllegalAccessException: class org.apache.velocity.runtime.parser.node.PropertyExecutor cannot access class sun.security.x509.X509CertImpl (in module java.base) because module java.base does not export sun.security.x509 to unnamed module @45ad6cad
          at java.base/jdk.internal.reflect.Reflection.newIllegalAccessException(Reflection.java:392)
          at java.base/java.lang.reflect.AccessibleObject.checkAccess(AccessibleObject.java:674)
          at java.base/java.lang.reflect.Method.invoke(Method.java:560)
          at org.apache.velocity.runtime.parser.node.PropertyExecutor.execute(PropertyExecutor.java:149)
          at org.apache.velocity.util.introspection.UberspectImpl$VelGetterImpl.invoke(UberspectImpl.java:722)
          at org.apache.velocity.runtime.parser.node.ASTIdentifier.execute(ASTIdentifier.java:217)
          ... 6 more
      

      It looks like Velocity is picking an inconvenient class on which to base its method invocation.

       

      Here is the test source.

      import java.io.OutputStreamWriter;
      import java.io.StringReader;
      import java.nio.charset.StandardCharsets;
      import java.security.cert.Certificate;
      import java.security.cert.X509Certificate;
      import java.security.cert.CertificateFactory;
      import org.apache.velocity.Template;
      import org.apache.velocity.VelocityContext;
      import org.apache.velocity.app.VelocityEngine;
      import org.apache.velocity.runtime.RuntimeServices;
      import org.apache.velocity.runtime.RuntimeSingleton;
      
      public class CertTest {
        private static final String certText = "-----BEGIN CERTIFICATE-----\n"
          + "MIICJTCCAaygAwIBAgIIXjahgh5+v08wCgYIKoZIzj0EAwMwaTEQMA4GA1UEBhMH\n"
          + "VW5rbm93bjEQMA4GA1UECBMHVW5rbm93bjEQMA4GA1UEBxMHVW5rbm93bjEQMA4G\n"
          + "A1UEChMHVW5rbm93bjEQMA4GA1UECxMHVW5rbm93bjENMAsGA1UEAxMEdGVzdDAe\n"
          + "Fw0yMzEwMDUxNzQyMzJaFw0yNDAxMDMxNzQyMzJaMGkxEDAOBgNVBAYTB1Vua25v\n"
          + "d24xEDAOBgNVBAgTB1Vua25vd24xEDAOBgNVBAcTB1Vua25vd24xEDAOBgNVBAoT\n"
          + "B1Vua25vd24xEDAOBgNVBAsTB1Vua25vd24xDTALBgNVBAMTBHRlc3QwdjAQBgcq\n"
          + "hkjOPQIBBgUrgQQAIgNiAARluamNquFohhtrjhN6Sq+QXVlb+/1GVHg0h10iDehm\n"
          + "msRkfPkugLIwRbLIaggzFkx66QcT4oIjhvM0Q1jM7a/9BhNUWJvZMa54M3Nh+K6P\n"
          + "fzp8tOGHe2EAHibDP1KSGHCjITAfMB0GA1UdDgQWBBSLy96Os2mUo7TiKAwRlEmq\n"
          + "dzOrCDAKBggqhkjOPQQDAwNnADBkAjBx+sqV2gzUusdOvwltH7f7sp5UtZMRFKF4\n"
          + "mRcGA7buAZN/YPUGgkiUZ6ZEJmw8Dn8CMEEgm8c2WTYdO/CQ5DRBbfIt1TcpiDxk\n"
          + "0vM+YZrSctwCJhK+3h3i4X990XvjJQ3Hmw==\n"
          + "-----END CERTIFICATE-----\n"
      ;
      
        private static final String templateText = "Test: $cert.notAfter\n";
      
        public static void main(String[] args) throws Exception {
          X509Certificate cert = (X509Certificate)CertificateFactory.getInstance("X.509").generateCertificate(new java.io.ByteArrayInputStream(certText.getBytes(StandardCharsets.US_ASCII)));    System.out.println("Cert notAfter=" + cert.getNotAfter());    VelocityContext ctx = new VelocityContext();
          ctx.put("cert", cert);    VelocityEngine ve = new VelocityEngine();
          ve.init();    RuntimeServices runtimeServices = RuntimeSingleton.getRuntimeServices();
          Template template = new Template();
          template.setRuntimeServices(runtimeServices);
          /// For Velocity 1.7:
          //template.setData(runtimeServices.parse(new StringReader(templateText), "Note Template"));    // For Velocity 2.x
          template.setData(runtimeServices.parse(new StringReader(templateText), template));    template.initDocument();    OutputStreamWriter out = new OutputStreamWriter(System.out);
          template.merge(ctx, out);
          out.flush();
        }
      }
      

      This fails in the same way running under both Velocity 2.3 and Velocity 1.7 (with a small required source change).

      Attachments

        Issue Links

          Activity

            People

              Unassigned Unassigned
              chris@christopherschultz.net Christopher Schultz
              Votes:
              0 Vote for this issue
              Watchers:
              2 Start watching this issue

              Dates

                Created:
                Updated:
                Resolved: