azure-sdk-for-java: [BUG] Occurs SecurityException when building native image based on Spring Cloud Azure Native support

Describe the bug When using native tools to build, the failure Fatal error: java.lang.SecurityException: class "com.azure.spring.cloud.autoconfigure.compatibility.AzureCompatibilityVerifierAutoConfiguration"'s signer information does not match signer information of other classes in the same package occurs.

Exception or Stack Trace

Fatal error: java.lang.SecurityException: class "com.azure.spring.cloud.autoconfigure.compatibility.AzureCompatibilityVerifierAutoConfiguration"'s signer information does not match signer information of other classes in the same package
        at java.base/java.lang.ClassLoader.checkCerts(ClassLoader.java:1151)
        at java.base/java.lang.ClassLoader.preDefineClass(ClassLoader.java:906)
        at java.base/java.lang.ClassLoader.defineClass(ClassLoader.java:1015)
        at java.base/java.security.SecureClassLoader.defineClass(SecureClassLoader.java:174)
        at java.base/java.net.URLClassLoader.defineClass(URLClassLoader.java:555)
        at java.base/java.net.URLClassLoader$1.run(URLClassLoader.java:458)
        at java.base/java.net.URLClassLoader$1.run(URLClassLoader.java:452)
        at java.base/java.security.AccessController.doPrivileged(Native Method)
        at java.base/java.net.URLClassLoader.findClass(URLClassLoader.java:451)
        at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:589)
        at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:522)
        at java.base/java.lang.Class.forName0(Native Method)
        at java.base/java.lang.Class.forName(Class.java:398)
        at com.oracle.svm.hosted.ImageClassLoader.forName(ImageClassLoader.java:285)
        at com.oracle.svm.hosted.ImageClassLoader.findClass(ImageClassLoader.java:278)
        at com.oracle.svm.hosted.config.ReflectionRegistryAdapter.resolveType(ReflectionRegistryAdapter.java:68)
        at com.oracle.svm.core.configure.ReflectionConfigurationParser.parseClass(ReflectionConfigurationParser.java:94)
        at com.oracle.svm.core.configure.ReflectionConfigurationParser.parseClassArray(ReflectionConfigurationParser.java:77)
        at com.oracle.svm.core.configure.ReflectionConfigurationParser.parseAndRegister(ReflectionConfigurationParser.java:72)
        at com.oracle.svm.hosted.config.ConfigurationParserUtils.doParseAndRegister(ConfigurationParserUtils.java:127)
        at com.oracle.svm.hosted.config.ConfigurationParserUtils.lambda$parseAndRegisterConfigurations$3(ConfigurationParserUtils.java:113)
        at java.base/java.util.stream.ReferencePipeline$4$1.accept(ReferencePipeline.java:212)
        at com.oracle.svm.hosted.config.ConfigurationParserUtils$1.tryAdvance(ConfigurationParserUtils.java:106)
        at java.base/java.util.Spliterator.forEachRemaining(Spliterator.java:326)
        at java.base/java.util.stream.ReferencePipeline$Head.forEach(ReferencePipeline.java:658)
        at java.base/java.util.stream.ReferencePipeline$7$1.accept(ReferencePipeline.java:274)
        at java.base/java.util.ArrayList$ArrayListSpliterator.forEachRemaining(ArrayList.java:1655)
        at java.base/java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:484)
        at java.base/java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:474)
        at java.base/java.util.stream.StreamSpliterators$WrappingSpliterator.forEachRemaining(StreamSpliterators.java:312)
        at java.base/java.util.stream.Streams$ConcatSpliterator.forEachRemaining(Streams.java:734)
        at java.base/java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:484)
        at java.base/java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:474)
        at java.base/java.util.stream.ReduceOps$ReduceOp.evaluateSequential(ReduceOps.java:913)
        at java.base/java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234)
        at java.base/java.util.stream.IntPipeline.reduce(IntPipeline.java:491)
        at java.base/java.util.stream.IntPipeline.sum(IntPipeline.java:449)
        at com.oracle.svm.hosted.config.ConfigurationParserUtils.parseAndRegisterConfigurations(ConfigurationParserUtils.java:115)
        at com.oracle.svm.reflect.hosted.ReflectionFeature.duringSetup(ReflectionFeature.java:185)
        at com.oracle.svm.hosted.NativeImageGenerator.lambda$setupNativeImage$16(NativeImageGenerator.java:847)
        at com.oracle.svm.hosted.FeatureHandler.forEachFeature(FeatureHandler.java:74)
        at com.oracle.svm.hosted.NativeImageGenerator.setupNativeImage(NativeImageGenerator.java:847)
        at com.oracle.svm.hosted.NativeImageGenerator.doRun(NativeImageGenerator.java:534)
        at com.oracle.svm.hosted.NativeImageGenerator.run(NativeImageGenerator.java:494)
        at com.oracle.svm.hosted.NativeImageGeneratorRunner.buildImage(NativeImageGeneratorRunner.java:426)
        at com.oracle.svm.hosted.NativeImageGeneratorRunner.build(NativeImageGeneratorRunner.java:587)
        at com.oracle.svm.hosted.NativeImageGeneratorRunner.main(NativeImageGeneratorRunner.java:126)
        at com.oracle.svm.hosted.NativeImageGeneratorRunner$JDK9Plus.main(NativeImageGeneratorRunner.java:617)

To Reproduce Run sample issue-azure-storage-native

Code Snippet Ref the sample project.

Expected behavior Build and exec successfully.

Setup (please complete the following information):

  • OS: [Windows 11]
  • IDE: [IntelliJ]
  • Library/Libraries: [com.azure.spring:spring-cloud-azure-starter-storage-blob:4.1.0, com.azure.spring:spring-cloud-azure-native-configuration:4.0.0-beta.1]
  • Java version: [11]
  • Frameworks: [Spring Boot 2.6.6]

Information Checklist Kindly make sure that you have added all the following information above and checkoff the required fields otherwise we will treat the issuer as an incomplete report

  • Bug Description Added
  • Repro Steps Added
  • Setup information Added

About this issue

  • Original URL
  • State: open
  • Created 2 years ago
  • Reactions: 1
  • Comments: 22 (13 by maintainers)

Most upvoted comments

For gradle bootRun you should configure something like that in app/build.gradle:

bootRun {
	systemProperty("java.security.properties", "/home/seb/playground/spring-aot-jarsigner-reproducer/custom.security")
	systemProperty('spring.aot.enabled', 'true')
}

See related Spring Boot documentation. It should be even possible to create the custom.security file in build.gradle.

For native image, you can configure the application module in app/build.gradle with

graalvmNative {
	binaries {
		main {
			buildArgs('-Djava.security.properties=/home/seb/playground/spring-aot-jarsigner-reproducer/custom.security')
		}
	}
}

With custom.security content behing:

jdk.jar.disabledAlgorithms=MD2, MD5, RSA, DSA

Works for me on spring-aot-jarsigner-reproducer

The only thing I am not sure yet is how to make this supported with Buildpacks, but let’s for now see if it works for you with Native Build Tools.

FYI, for the Gradle project to use a project level custom.security file, you could set as following:

graalvmNative {
  binaries {
    main {
      buildArgs('-Djava.security.properties=' + file("$rootDir/custom.security").absolutePath)
    }
  }  
}
bootRun {
  systemProperty("java.security.properties", file("$rootDir/custom.security").absolutePath)
  systemProperty('spring.aot.enabled', 'true')
}

FYI the currrent workaround proposed to get both Native Build Tools and Buildpacks support is:

<build>
   <plugins>
      <plugin>
         <groupId>org.graalvm.buildtools</groupId>
         <artifactId>native-maven-plugin</artifactId>
         <configuration>
            <buildArgs>
               <arg>-Djava.security.properties=src/main/resources/custom.security</arg>
            </buildArgs>
         </configuration>
      </plugin>
      <plugin>
         <groupId>org.springframework.boot</groupId>
         <artifactId>spring-boot-maven-plugin</artifactId>
         <configuration>
            <image>
               <env>
                  <BP_NATIVE_IMAGE_BUILD_ARGUMENTS>-Djava.security.properties=/workspace/BOOT-INF/classes/custom.security</BP_NATIVE_IMAGE_BUILD_ARGUMENTS>
               </env>
            </image>
         </configuration>
      </plugin>
   </plugins>
</build>

With an src/main/resources/custom.security file with the following content:

jdk.jar.disabledAlgorithms=MD2, MD5, RSA, DSA

I suggest to document that properly to allow Azure Java SDK to be able to use Spring Boot 3 AOT/native support.

It is currently blocked, and both native build tool and Buildpacks will encounter it.