0

I am trying to create a native executable from my Spring Boot 3.0.7 app (Java 17) using GraalVM. I am using GraalVM in a Docker build to create the native executable. I am using the "jasypt-spring-boot" (3.0.5) library to store the required app passwords in encrypted form.

The compilation of the app also seems to work from my point of view. However, the following error occurs when starting the app:


APPLICATION FAILED TO START


Description:

Failed to bind properties under 'bla.passwd' to java.lang.String:

Reason: org.jasypt.exceptions.EncryptionInitializationException: Cannot find a valid UNICODE normalizer: neither java.text.Normalizer nor com.ibm.icu.text.Normalizer have been found at the classpath. If you are using a version of the JDK older than JavaSE 6, you should include the icu4j library in your classpath.

The encrypted passwords contain only ASCII characters.

Update: I tried adding some reflection hints in my reflection-config.json, unfortunately without success:

  {
    "name": "com.ibm.icu.text.Normalizer",
    "allDeclaredConstructors": true,
    "allPublicConstructors": true,
    "allDeclaredMethods": true,
    "allPublicMethods": true,
    "allDeclaredFields": true,
    "allPublicFields": true,
    "allDeclaredClasses": true,
    "allPublicClasses": true
  },
  {
    "name": "java.text.Normalizer",
    "allDeclaredConstructors": true,
    "allPublicConstructors": true,
    "allDeclaredMethods": true,
    "allPublicMethods": true,
    "allDeclaredFields": true,
    "allPublicFields": true,
    "allDeclaredClasses": true,
    "allPublicClasses": true
  }

In my gradle script I have set the following configuration:

graalvmNative {
    binaries {
        all {
            resources.autodetect()
        }
        main {
            imageName.set('my-service')
            buildArgs.add('--verbose')
            buildArgs.add('-H:ReflectionConfigurationFiles=../../../src/main/resources/reflect-config.json')
        }
    }
}

I have added a small demo repository to demonstrate the issue: https://github.com/benocms/spring-native.test.git

Has anyone here had similar experiences and can possibly give me a hint?

Thank you very much.

Ben
  • 290
  • 2
  • 17
  • The file should be named `reflect-config.json`. Also, its location is important. What's its path relative to the root of your project? – Andy Wilkinson May 31 '23 at 16:08
  • I use the graalvmNative plugin from gradle with the configuration option 'ReflectionConfigurationFiles'. The value points to the file './../../src/main/resources/reflect-config.json'. – Ben Jun 01 '23 at 15:43
  • Why does the path begin `../../../`? Have you verified that Graal is finding and using it when building the image? – Andy Wilkinson Jun 01 '23 at 19:48
  • Without the trailing '../../../' the reflect-config.json cannot be found and the build fails with an appropriate error message. When I search for the "com.ibm.icu.text.Normalizer" value in the target image, the following files are present: ./src/main/resources/reflect-config.json:157: "name": "com.ibm.icu.text.Normalizer", ./src/main/resources/reflect-config.json:168: "name": "java.text.Normalizer", ./build/resources/main/reflect-config.json:157: "name": "com.ibm.icu.text.Normalizer", ./build/resources/main/reflect-config.json:168: "name": "java.text.Normalizer", – Ben Jun 01 '23 at 21:43
  • Of course, I didn't mean 'trailing' but prefixed. – Ben Jun 02 '23 at 08:22
  • I have added a small demo repository to demonstrate the problem, I hope this is helpful (https://github.com/benocms/spring-native.test.git). – Ben Jun 02 '23 at 10:37

1 Answers1

0

Jasypt uses reflection to load the normalizer classes. It tries com.ibm.icu.text.Normalizer first and then, if that doesn't work, it tries java.text.Normalizer.

GraalVM can't tell that these classes are required so they aren't included in the native image and aren't, therefore, available to be loaded via reflection. You can correct this by providing some hints to GraalVM.

Andy Wilkinson
  • 108,729
  • 24
  • 257
  • 242
  • Thank you very much for the hint. I tried to add some reflection hints in the json file (see my updated question). Unfortunately without success. – Ben May 31 '23 at 08:24