From 63a20be502c9a8cfd95dc14fa017e7d84b07bc73 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Deleuze?= Date: Fri, 1 Sep 2023 12:29:16 +0200 Subject: [PATCH] Optimize Hibernate native footprint by making ByteBuddy unreachable As a workaround before a proper solution the Spring team is trying to find with the Hibernate team in a future version of Hibernate, this commit introduces 2 GraalVM substitutions that should allow to remove ByteBuddy reachability with Hibernate 6.3. Closes gh-29549 --- .../jpa/vendor/Target_BytecodeProvider.java | 41 ++++++++++++++++ .../Target_BytecodeProviderInitiator.java | 49 +++++++++++++++++++ src/checkstyle/checkstyle-suppressions.xml | 1 + 3 files changed, 91 insertions(+) create mode 100644 spring-orm/src/main/java/org/springframework/orm/jpa/vendor/Target_BytecodeProvider.java create mode 100644 spring-orm/src/main/java/org/springframework/orm/jpa/vendor/Target_BytecodeProviderInitiator.java diff --git a/spring-orm/src/main/java/org/springframework/orm/jpa/vendor/Target_BytecodeProvider.java b/spring-orm/src/main/java/org/springframework/orm/jpa/vendor/Target_BytecodeProvider.java new file mode 100644 index 0000000000..7da52126ae --- /dev/null +++ b/spring-orm/src/main/java/org/springframework/orm/jpa/vendor/Target_BytecodeProvider.java @@ -0,0 +1,41 @@ +/* + * Copyright 2002-2023 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.orm.jpa.vendor; + +import java.util.Map; + +import com.oracle.svm.core.annotate.Substitute; +import com.oracle.svm.core.annotate.TargetClass; +import org.hibernate.bytecode.spi.ReflectionOptimizer; +import org.hibernate.property.access.spi.PropertyAccess; + +/** + * Hibernate 6.3+ substitution designed to leniently return {@code null}, as authorized by the API, to avoid throwing an + * {@code HibernateException}. + * TODO Ask Hibernate team to fix this as it looks like a bug + * + * @author Sebastien Deleuze + * @since 6.1 + */ +@TargetClass(className = "org.hibernate.bytecode.internal.none.BytecodeProviderImpl") +final class Target_BytecodeProvider { + + @Substitute + public ReflectionOptimizer getReflectionOptimizer(Class clazz, Map propertyAccessMap) { + return null; + } +} diff --git a/spring-orm/src/main/java/org/springframework/orm/jpa/vendor/Target_BytecodeProviderInitiator.java b/spring-orm/src/main/java/org/springframework/orm/jpa/vendor/Target_BytecodeProviderInitiator.java new file mode 100644 index 0000000000..c774a95823 --- /dev/null +++ b/spring-orm/src/main/java/org/springframework/orm/jpa/vendor/Target_BytecodeProviderInitiator.java @@ -0,0 +1,49 @@ +/* + * Copyright 2002-2023 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.orm.jpa.vendor; + +import com.oracle.svm.core.annotate.Alias; +import com.oracle.svm.core.annotate.RecomputeFieldValue; +import com.oracle.svm.core.annotate.Substitute; +import com.oracle.svm.core.annotate.TargetClass; +import org.hibernate.bytecode.spi.BytecodeProvider; + +import static com.oracle.svm.core.annotate.RecomputeFieldValue.Kind; + +/** + * Hibernate substitution designed to prevent ByteBuddy reachability on native, and to enforce the + * usage of {@code org.hibernate.bytecode.internal.none.BytecodeProviderImpl} with Hibernate 6.3+. + * TODO Collaborate with Hibernate team on a substitution-less alternative that does not require a custom list of StandardServiceInitiator + * + * @author Sebastien Deleuze + * @since 6.1 + */ +@TargetClass(className = "org.hibernate.bytecode.internal.BytecodeProviderInitiator") +final class Target_BytecodeProviderInitiator { + + @Alias + public static String BYTECODE_PROVIDER_NAME_NONE; + + @Alias + @RecomputeFieldValue(kind = Kind.FromAlias) + public static String BYTECODE_PROVIDER_NAME_DEFAULT = BYTECODE_PROVIDER_NAME_NONE; + + @Substitute + public static BytecodeProvider buildBytecodeProvider(String providerName) { + return new org.hibernate.bytecode.internal.none.BytecodeProviderImpl(); + } +} diff --git a/src/checkstyle/checkstyle-suppressions.xml b/src/checkstyle/checkstyle-suppressions.xml index 6b76324916..53f642bafb 100644 --- a/src/checkstyle/checkstyle-suppressions.xml +++ b/src/checkstyle/checkstyle-suppressions.xml @@ -84,6 +84,7 @@ +