diff --git a/hibernate-core/src/main/java/org/hibernate/collection/spi/PersistentArrayHolder.java b/hibernate-core/src/main/java/org/hibernate/collection/spi/PersistentArrayHolder.java index 426ca5b88ddb..755cf16840c6 100644 --- a/hibernate-core/src/main/java/org/hibernate/collection/spi/PersistentArrayHolder.java +++ b/hibernate-core/src/main/java/org/hibernate/collection/spi/PersistentArrayHolder.java @@ -18,6 +18,7 @@ import org.hibernate.engine.spi.SharedSessionContractImplementor; import org.hibernate.internal.CoreLogging; import org.hibernate.internal.CoreMessageLogger; +import org.hibernate.internal.build.AllowReflection; import org.hibernate.metamodel.mapping.PluralAttributeMapping; import org.hibernate.persister.collection.CollectionPersister; import org.hibernate.type.Type; @@ -34,6 +35,7 @@ * @author Gavin King */ @Incubating +@AllowReflection // We need the ability to create arrays of the same type as in the model. public class PersistentArrayHolder extends AbstractPersistentCollection { private static final CoreMessageLogger LOG = CoreLogging.messageLogger( PersistentArrayHolder.class ); diff --git a/hibernate-core/src/main/java/org/hibernate/dialect/JsonHelper.java b/hibernate-core/src/main/java/org/hibernate/dialect/JsonHelper.java index 76594c74c14e..ce50d1b6f587 100644 --- a/hibernate-core/src/main/java/org/hibernate/dialect/JsonHelper.java +++ b/hibernate-core/src/main/java/org/hibernate/dialect/JsonHelper.java @@ -18,6 +18,7 @@ import java.util.Objects; import org.hibernate.Internal; +import org.hibernate.internal.build.AllowReflection; import org.hibernate.internal.util.CharSequenceHelper; import org.hibernate.internal.util.collections.ArrayHelper; import org.hibernate.metamodel.mapping.EmbeddableMappingType; @@ -1612,6 +1613,7 @@ public Object[] toArray() { } @Override + @AllowReflection // We need the ability to create arrays of requested types dynamically. public T[] toArray(T[] a) { //noinspection unchecked final T[] r = a.length >= size diff --git a/hibernate-core/src/main/java/org/hibernate/dialect/function/array/DdlTypeHelper.java b/hibernate-core/src/main/java/org/hibernate/dialect/function/array/DdlTypeHelper.java index c4beb0c99c3e..154bd16f7a1c 100644 --- a/hibernate-core/src/main/java/org/hibernate/dialect/function/array/DdlTypeHelper.java +++ b/hibernate-core/src/main/java/org/hibernate/dialect/function/array/DdlTypeHelper.java @@ -10,6 +10,7 @@ import org.hibernate.dialect.Dialect; import org.hibernate.engine.jdbc.Size; +import org.hibernate.internal.build.AllowReflection; import org.hibernate.metamodel.mapping.JdbcMappingContainer; import org.hibernate.metamodel.mapping.SqlTypedMapping; import org.hibernate.metamodel.model.domain.DomainType; @@ -24,6 +25,7 @@ public class DdlTypeHelper { @SuppressWarnings("unchecked") + @AllowReflection public static BasicType resolveArrayType(DomainType elementType, TypeConfiguration typeConfiguration) { @SuppressWarnings("unchecked") final BasicPluralJavaType arrayJavaType = (BasicPluralJavaType) typeConfiguration.getJavaTypeRegistry() .getDescriptor( diff --git a/hibernate-core/src/main/java/org/hibernate/dialect/function/array/JsonArrayViaElementArgumentReturnTypeResolver.java b/hibernate-core/src/main/java/org/hibernate/dialect/function/array/JsonArrayViaElementArgumentReturnTypeResolver.java index 97a5228b6c69..10605215124e 100644 --- a/hibernate-core/src/main/java/org/hibernate/dialect/function/array/JsonArrayViaElementArgumentReturnTypeResolver.java +++ b/hibernate-core/src/main/java/org/hibernate/dialect/function/array/JsonArrayViaElementArgumentReturnTypeResolver.java @@ -8,6 +8,7 @@ import java.util.List; import java.util.function.Supplier; +import org.hibernate.internal.build.AllowReflection; import org.hibernate.metamodel.mapping.BasicValuedMapping; import org.hibernate.metamodel.mapping.MappingModelExpressible; import org.hibernate.metamodel.model.domain.DomainType; @@ -78,6 +79,7 @@ public BasicValuedMapping resolveFunctionReturnType( return null; } + @AllowReflection public static BasicType resolveJsonArrayType(DomainType elementType, TypeConfiguration typeConfiguration) { final Class arrayClass = Array.newInstance( elementType.getBindableJavaType(), 0 ).getClass(); @SuppressWarnings("unchecked") diff --git a/hibernate-core/src/main/java/org/hibernate/event/service/internal/EventListenerGroupImpl.java b/hibernate-core/src/main/java/org/hibernate/event/service/internal/EventListenerGroupImpl.java index 840516bba6e1..3d9081ad082b 100644 --- a/hibernate-core/src/main/java/org/hibernate/event/service/internal/EventListenerGroupImpl.java +++ b/hibernate-core/src/main/java/org/hibernate/event/service/internal/EventListenerGroupImpl.java @@ -22,6 +22,7 @@ import org.hibernate.event.service.spi.EventListenerRegistrationException; import org.hibernate.event.service.spi.JpaBootstrapSensitive; import org.hibernate.event.spi.EventType; +import org.hibernate.internal.build.AllowReflection; import org.hibernate.jpa.event.spi.CallbackRegistry; import org.hibernate.jpa.event.spi.CallbackRegistryConsumer; @@ -350,6 +351,7 @@ private void handleListenerAddition(T listener, Consumer additionHandler) { } @SuppressWarnings("unchecked") + @AllowReflection // Possible array types are registered in org.hibernate.graalvm.internal.StaticClassLists.typesNeedingArrayCopy private T[] createListenerArrayForWrite(int len) { return (T[]) Array.newInstance( eventType.baseListenerInterface(), len ); } diff --git a/hibernate-core/src/main/java/org/hibernate/event/service/internal/EventListenerRegistryImpl.java b/hibernate-core/src/main/java/org/hibernate/event/service/internal/EventListenerRegistryImpl.java index 95111991da73..0d1247ac9a2a 100644 --- a/hibernate-core/src/main/java/org/hibernate/event/service/internal/EventListenerRegistryImpl.java +++ b/hibernate-core/src/main/java/org/hibernate/event/service/internal/EventListenerRegistryImpl.java @@ -38,6 +38,7 @@ import org.hibernate.event.service.spi.EventListenerRegistrationException; import org.hibernate.event.service.spi.EventListenerRegistry; import org.hibernate.event.spi.EventType; +import org.hibernate.internal.build.AllowReflection; import org.hibernate.jpa.event.spi.CallbackRegistry; import static org.hibernate.event.spi.EventType.AUTO_FLUSH; @@ -122,6 +123,7 @@ public final void setListeners(EventType type, Class... list } @SafeVarargs + @AllowReflection // Possible array types are registered in org.hibernate.graalvm.internal.StaticClassLists.typesNeedingArrayCopy private T[] resolveListenerInstances(EventType type, Class... listenerClasses) { @SuppressWarnings("unchecked") T[] listeners = (T[]) Array.newInstance( type.baseListenerInterface(), listenerClasses.length ); diff --git a/hibernate-core/src/main/java/org/hibernate/internal/build/AllowReflection.java b/hibernate-core/src/main/java/org/hibernate/internal/build/AllowReflection.java new file mode 100644 index 000000000000..456cd4574c09 --- /dev/null +++ b/hibernate-core/src/main/java/org/hibernate/internal/build/AllowReflection.java @@ -0,0 +1,18 @@ +/* + * SPDX-License-Identifier: LGPL-2.1-or-later + * Copyright Red Hat Inc. and Hibernate Authors + */ +package org.hibernate.internal.build; + +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +import static java.lang.annotation.ElementType.CONSTRUCTOR; +import static java.lang.annotation.ElementType.METHOD; +import static java.lang.annotation.ElementType.TYPE; + +@Retention( RetentionPolicy.CLASS ) +@Target({ TYPE, METHOD, CONSTRUCTOR }) +public @interface AllowReflection { +} diff --git a/hibernate-core/src/main/java/org/hibernate/internal/util/collections/ArrayHelper.java b/hibernate-core/src/main/java/org/hibernate/internal/util/collections/ArrayHelper.java index 79c115b981f6..556792813a32 100644 --- a/hibernate-core/src/main/java/org/hibernate/internal/util/collections/ArrayHelper.java +++ b/hibernate-core/src/main/java/org/hibernate/internal/util/collections/ArrayHelper.java @@ -18,6 +18,7 @@ import org.hibernate.HibernateException; import org.hibernate.LockMode; import org.hibernate.LockOptions; +import org.hibernate.internal.build.AllowReflection; import org.hibernate.type.Type; public final class ArrayHelper { @@ -59,6 +60,7 @@ public static int indexOf(Object[] array, int end, Object object) { } @SuppressWarnings("unchecked") + @AllowReflection public static T[] filledArray(T value, Class valueJavaType, int size) { final T[] array = (T[]) Array.newInstance( valueJavaType, size ); Arrays.fill( array, value ); @@ -202,6 +204,7 @@ public static int[] join(int[] x, int[] y) { } @SuppressWarnings("unchecked") + @AllowReflection public static T[] join(T[] x, T... y) { T[] result = (T[]) Array.newInstance( x.getClass().getComponentType(), x.length + y.length ); System.arraycopy( x, 0, result, 0, x.length ); @@ -520,6 +523,7 @@ public static void forEach(T[] array, Consumer consumer) { } @SuppressWarnings("unchecked") + @AllowReflection public static T[] newInstance(Class elementType, int length) { return (T[]) Array.newInstance( elementType, length ); } diff --git a/hibernate-core/src/main/java/org/hibernate/jpa/event/internal/CallbackRegistryImpl.java b/hibernate-core/src/main/java/org/hibernate/jpa/event/internal/CallbackRegistryImpl.java index 5c52ad61fda9..c65ee9116eaf 100644 --- a/hibernate-core/src/main/java/org/hibernate/jpa/event/internal/CallbackRegistryImpl.java +++ b/hibernate-core/src/main/java/org/hibernate/jpa/event/internal/CallbackRegistryImpl.java @@ -9,6 +9,7 @@ import jakarta.persistence.PersistenceException; +import org.hibernate.internal.build.AllowReflection; import org.hibernate.internal.util.collections.ArrayHelper; import org.hibernate.internal.util.collections.MapBackedClassValue; import org.hibernate.internal.util.collections.ReadOnlyMap; @@ -168,6 +169,7 @@ public static class Builder { private final Map, Callback[]> postUpdates = new HashMap<>(); private final Map, Callback[]> postLoads = new HashMap<>(); + @AllowReflection public void registerCallbacks(Class entityClass, Callback[] callbacks) { if ( callbacks != null ) { for ( Callback callback : callbacks ) { diff --git a/hibernate-core/src/main/java/org/hibernate/loader/ast/internal/AbstractCollectionBatchLoader.java b/hibernate-core/src/main/java/org/hibernate/loader/ast/internal/AbstractCollectionBatchLoader.java index b19ef0a592f0..7ac72a5222b2 100644 --- a/hibernate-core/src/main/java/org/hibernate/loader/ast/internal/AbstractCollectionBatchLoader.java +++ b/hibernate-core/src/main/java/org/hibernate/loader/ast/internal/AbstractCollectionBatchLoader.java @@ -11,6 +11,7 @@ import org.hibernate.engine.spi.PersistenceContext; import org.hibernate.engine.spi.SessionFactoryImplementor; import org.hibernate.engine.spi.SharedSessionContractImplementor; +import org.hibernate.internal.build.AllowReflection; import org.hibernate.loader.ast.spi.CollectionBatchLoader; import org.hibernate.metamodel.mapping.NonAggregatedIdentifierMapping; import org.hibernate.metamodel.mapping.PluralAttributeMapping; @@ -126,6 +127,7 @@ protected void finishInitializingKey(Object key, SharedSessionContractImplemento } + @AllowReflection Object[] resolveKeysToInitialize(Object keyBeingLoaded, SharedSessionContractImplementor session) { final int length = getDomainBatchSize(); final Object[] keysToInitialize = (Object[]) Array.newInstance( diff --git a/hibernate-core/src/main/java/org/hibernate/loader/ast/internal/AbstractMultiIdEntityLoader.java b/hibernate-core/src/main/java/org/hibernate/loader/ast/internal/AbstractMultiIdEntityLoader.java index 6d70c1076e4f..1e5e8951e1d2 100644 --- a/hibernate-core/src/main/java/org/hibernate/loader/ast/internal/AbstractMultiIdEntityLoader.java +++ b/hibernate-core/src/main/java/org/hibernate/loader/ast/internal/AbstractMultiIdEntityLoader.java @@ -11,6 +11,7 @@ import org.hibernate.engine.spi.EntityKey; import org.hibernate.engine.spi.SessionFactoryImplementor; import org.hibernate.event.spi.EventSource; +import org.hibernate.internal.build.AllowReflection; import org.hibernate.loader.ast.spi.MultiIdEntityLoader; import org.hibernate.loader.ast.spi.MultiIdLoadOptions; import org.hibernate.loader.internal.CacheLoadHelper.PersistenceContextEntry; @@ -42,6 +43,7 @@ public abstract class AbstractMultiIdEntityLoader implements MultiIdEntityLoa private final EntityIdentifierMapping identifierMapping; protected final Object[] idArray; + @AllowReflection public AbstractMultiIdEntityLoader(EntityMappingType entityDescriptor, SessionFactoryImplementor sessionFactory) { this.entityDescriptor = entityDescriptor; this.sessionFactory = sessionFactory; diff --git a/hibernate-core/src/main/java/org/hibernate/loader/ast/internal/CollectionBatchLoaderArrayParam.java b/hibernate-core/src/main/java/org/hibernate/loader/ast/internal/CollectionBatchLoaderArrayParam.java index c4b543734cfa..029dcd38671e 100644 --- a/hibernate-core/src/main/java/org/hibernate/loader/ast/internal/CollectionBatchLoaderArrayParam.java +++ b/hibernate-core/src/main/java/org/hibernate/loader/ast/internal/CollectionBatchLoaderArrayParam.java @@ -13,6 +13,7 @@ import org.hibernate.engine.spi.SessionFactoryImplementor; import org.hibernate.engine.spi.SharedSessionContractImplementor; import org.hibernate.engine.spi.SubselectFetch; +import org.hibernate.internal.build.AllowReflection; import org.hibernate.loader.ast.spi.CollectionBatchLoader; import org.hibernate.loader.ast.spi.SqlArrayMultiKeyLoader; import org.hibernate.metamodel.mapping.ForeignKeyDescriptor; @@ -51,6 +52,7 @@ public class CollectionBatchLoaderArrayParam private final SelectStatement sqlSelect; private final JdbcOperationQuerySelect jdbcSelectOperation; + @AllowReflection public CollectionBatchLoaderArrayParam( int domainBatchSize, LoadQueryInfluencers loadQueryInfluencers, @@ -115,6 +117,7 @@ public PersistentCollection load(Object keyBeingLoaded, SharedSessionContract } + @AllowReflection private PersistentCollection loadEmbeddable( Object keyBeingLoaded, SharedSessionContractImplementor session, @@ -216,6 +219,7 @@ void finishInitializingKeys(Object[] keys, SharedSessionContractImplementor sess } @Override + @AllowReflection Object[] resolveKeysToInitialize(Object keyBeingLoaded, SharedSessionContractImplementor session) { final ForeignKeyDescriptor keyDescriptor = getLoadable().getKeyDescriptor(); if( keyDescriptor.isEmbedded()){ diff --git a/hibernate-core/src/main/java/org/hibernate/loader/ast/internal/EntityBatchLoaderArrayParam.java b/hibernate-core/src/main/java/org/hibernate/loader/ast/internal/EntityBatchLoaderArrayParam.java index 08cf5fd13bf5..3a5213eb19fb 100644 --- a/hibernate-core/src/main/java/org/hibernate/loader/ast/internal/EntityBatchLoaderArrayParam.java +++ b/hibernate-core/src/main/java/org/hibernate/loader/ast/internal/EntityBatchLoaderArrayParam.java @@ -11,6 +11,7 @@ import org.hibernate.LockOptions; import org.hibernate.engine.spi.LoadQueryInfluencers; import org.hibernate.engine.spi.SharedSessionContractImplementor; +import org.hibernate.internal.build.AllowReflection; import org.hibernate.loader.ast.spi.SqlArrayMultiKeyLoader; import org.hibernate.metamodel.mapping.BasicEntityIdentifierMapping; import org.hibernate.metamodel.mapping.EntityIdentifierMapping; @@ -58,6 +59,7 @@ public class EntityBatchLoaderArrayParam * {@link EntityIdentifierMapping} is not available at that time. On first use, we know we * have it available */ + @AllowReflection public EntityBatchLoaderArrayParam( int domainBatchSize, EntityMappingType entityDescriptor, @@ -106,6 +108,7 @@ public int getDomainBatchSize() { return domainBatchSize; } + @AllowReflection protected Object[] resolveIdsToInitialize(Object pkValue, SharedSessionContractImplementor session) { //TODO: should this really be different to EntityBatchLoaderInPredicate impl? final Class idType = identifierMapping.getJavaType().getJavaTypeClass(); diff --git a/hibernate-core/src/main/java/org/hibernate/loader/ast/internal/LoaderHelper.java b/hibernate-core/src/main/java/org/hibernate/loader/ast/internal/LoaderHelper.java index 885b46e10def..3ad14036c4e3 100644 --- a/hibernate-core/src/main/java/org/hibernate/loader/ast/internal/LoaderHelper.java +++ b/hibernate-core/src/main/java/org/hibernate/loader/ast/internal/LoaderHelper.java @@ -21,6 +21,7 @@ import org.hibernate.event.monitor.spi.EventMonitor; import org.hibernate.event.spi.EventSource; import org.hibernate.event.monitor.spi.DiagnosticEvent; +import org.hibernate.internal.build.AllowReflection; import org.hibernate.loader.LoaderLogging; import org.hibernate.metamodel.mapping.BasicValuedModelPart; import org.hibernate.metamodel.mapping.EntityMappingType; @@ -202,6 +203,7 @@ public static K[] normalizeKeys( * @param elementClass The type of the array elements. See {@link Class#getComponentType()} * @param length The length to which the array should be created. This is usually zero for Hibernate uses */ + @AllowReflection public static X[] createTypedArray(Class elementClass, @SuppressWarnings("SameParameterValue") int length) { //noinspection unchecked return (X[]) Array.newInstance( elementClass, length ); diff --git a/hibernate-core/src/main/java/org/hibernate/sql/results/internal/StandardRowReader.java b/hibernate-core/src/main/java/org/hibernate/sql/results/internal/StandardRowReader.java index 1e53ddbffe4a..a34b24fe6c4c 100644 --- a/hibernate-core/src/main/java/org/hibernate/sql/results/internal/StandardRowReader.java +++ b/hibernate-core/src/main/java/org/hibernate/sql/results/internal/StandardRowReader.java @@ -9,6 +9,7 @@ import java.util.List; import org.hibernate.engine.spi.EntityKey; +import org.hibernate.internal.build.AllowReflection; import org.hibernate.sql.results.graph.DomainResultAssembler; import org.hibernate.sql.results.graph.Initializer; import org.hibernate.sql.results.graph.InitializerData; @@ -130,6 +131,7 @@ public boolean hasCollectionInitializers() { } @Override + @AllowReflection public T readRow(RowProcessingState rowProcessingState) { coordinateInitializers( rowProcessingState ); diff --git a/hibernate-core/src/main/java/org/hibernate/type/ArrayType.java b/hibernate-core/src/main/java/org/hibernate/type/ArrayType.java index 28083585deb3..68c570712195 100644 --- a/hibernate-core/src/main/java/org/hibernate/type/ArrayType.java +++ b/hibernate-core/src/main/java/org/hibernate/type/ArrayType.java @@ -16,6 +16,7 @@ import org.hibernate.collection.spi.PersistentCollection; import org.hibernate.engine.spi.SessionFactoryImplementor; import org.hibernate.engine.spi.SharedSessionContractImplementor; +import org.hibernate.internal.build.AllowReflection; import org.hibernate.metamodel.CollectionClassification; import org.hibernate.persister.collection.CollectionPersister; @@ -26,6 +27,7 @@ * A type for persistent arrays. * @author Gavin King */ +@AllowReflection public class ArrayType extends CollectionType { private final Class elementClass; diff --git a/hibernate-core/src/main/java/org/hibernate/type/descriptor/converter/internal/ArrayConverter.java b/hibernate-core/src/main/java/org/hibernate/type/descriptor/converter/internal/ArrayConverter.java index fa228e05adaf..520b46560f52 100644 --- a/hibernate-core/src/main/java/org/hibernate/type/descriptor/converter/internal/ArrayConverter.java +++ b/hibernate-core/src/main/java/org/hibernate/type/descriptor/converter/internal/ArrayConverter.java @@ -6,6 +6,7 @@ import java.lang.reflect.Array; +import org.hibernate.internal.build.AllowReflection; import org.hibernate.type.descriptor.converter.spi.BasicValueConverter; import org.hibernate.type.descriptor.java.JavaType; @@ -18,6 +19,7 @@ * @param the unconverted array type * @param the converted array type */ +@AllowReflection public class ArrayConverter implements BasicValueConverter { private final BasicValueConverter elementConverter; diff --git a/hibernate-core/src/main/java/org/hibernate/type/descriptor/converter/internal/CollectionConverter.java b/hibernate-core/src/main/java/org/hibernate/type/descriptor/converter/internal/CollectionConverter.java index 6e9c8bcc9938..c997d216b77a 100644 --- a/hibernate-core/src/main/java/org/hibernate/type/descriptor/converter/internal/CollectionConverter.java +++ b/hibernate-core/src/main/java/org/hibernate/type/descriptor/converter/internal/CollectionConverter.java @@ -7,6 +7,7 @@ import java.lang.reflect.Array; import java.util.Collection; +import org.hibernate.internal.build.AllowReflection; import org.hibernate.type.descriptor.converter.spi.BasicValueConverter; import org.hibernate.type.descriptor.java.JavaType; import org.hibernate.type.descriptor.java.spi.BasicCollectionJavaType; @@ -43,6 +44,7 @@ public X toDomainValue(Y relationalForm) { } @Override + @AllowReflection public Y toRelationalValue(X domainForm) { if ( domainForm == null ) { return null; diff --git a/hibernate-core/src/main/java/org/hibernate/type/descriptor/java/AbstractArrayJavaType.java b/hibernate-core/src/main/java/org/hibernate/type/descriptor/java/AbstractArrayJavaType.java index c359ba704b01..333f2cce40a7 100644 --- a/hibernate-core/src/main/java/org/hibernate/type/descriptor/java/AbstractArrayJavaType.java +++ b/hibernate-core/src/main/java/org/hibernate/type/descriptor/java/AbstractArrayJavaType.java @@ -8,6 +8,7 @@ import org.hibernate.MappingException; import org.hibernate.dialect.Dialect; +import org.hibernate.internal.build.AllowReflection; import org.hibernate.tool.schema.extract.spi.ColumnTypeInformation; import org.hibernate.type.descriptor.converter.internal.ArrayConverter; import org.hibernate.type.BasicArrayType; @@ -20,6 +21,7 @@ import org.hibernate.type.descriptor.jdbc.JdbcTypeIndicators; import org.hibernate.type.spi.TypeConfiguration; +@AllowReflection public abstract class AbstractArrayJavaType extends AbstractClassJavaType implements BasicPluralJavaType { diff --git a/hibernate-core/src/main/java/org/hibernate/type/descriptor/java/ArrayJavaType.java b/hibernate-core/src/main/java/org/hibernate/type/descriptor/java/ArrayJavaType.java index e129da661be1..7fb49c195ab3 100644 --- a/hibernate-core/src/main/java/org/hibernate/type/descriptor/java/ArrayJavaType.java +++ b/hibernate-core/src/main/java/org/hibernate/type/descriptor/java/ArrayJavaType.java @@ -14,6 +14,7 @@ import org.hibernate.dialect.Dialect; import org.hibernate.engine.jdbc.BinaryStream; import org.hibernate.engine.jdbc.internal.ArrayBackedBinaryStream; +import org.hibernate.internal.build.AllowReflection; import org.hibernate.internal.util.SerializationHelper; import org.hibernate.tool.schema.extract.spi.ColumnTypeInformation; import org.hibernate.type.BasicPluralType; @@ -29,6 +30,7 @@ * @author Christian Beikov * @author Jordan Gigov */ +@AllowReflection public class ArrayJavaType extends AbstractArrayJavaType { public ArrayJavaType(BasicType baseDescriptor) { @@ -376,6 +378,7 @@ private T[] fromBytes(byte[] bytes) { } } + @AllowReflection private static class ArrayMutabilityPlan implements MutabilityPlan { private final Class componentClass; diff --git a/hibernate-core/src/main/java/org/hibernate/type/descriptor/java/ArrayMutabilityPlan.java b/hibernate-core/src/main/java/org/hibernate/type/descriptor/java/ArrayMutabilityPlan.java index db71278e10a7..892aaca02963 100644 --- a/hibernate-core/src/main/java/org/hibernate/type/descriptor/java/ArrayMutabilityPlan.java +++ b/hibernate-core/src/main/java/org/hibernate/type/descriptor/java/ArrayMutabilityPlan.java @@ -3,6 +3,8 @@ * Copyright Red Hat Inc. and Hibernate Authors */ package org.hibernate.type.descriptor.java; +import org.hibernate.internal.build.AllowReflection; + import java.lang.reflect.Array; /** @@ -15,6 +17,7 @@ public class ArrayMutabilityPlan extends MutableMutabilityPlan { public static final ArrayMutabilityPlan INSTANCE = new ArrayMutabilityPlan(); @SuppressWarnings({ "unchecked", "SuspiciousSystemArraycopy" }) + @AllowReflection public T deepCopyNotNull(T value) { if ( ! value.getClass().isArray() ) { // ugh! cannot find a way to properly define the type signature here diff --git a/hibernate-core/src/main/java/org/hibernate/type/descriptor/java/BooleanPrimitiveArrayJavaType.java b/hibernate-core/src/main/java/org/hibernate/type/descriptor/java/BooleanPrimitiveArrayJavaType.java index 2d6b4e07f889..a7ad513fdc57 100644 --- a/hibernate-core/src/main/java/org/hibernate/type/descriptor/java/BooleanPrimitiveArrayJavaType.java +++ b/hibernate-core/src/main/java/org/hibernate/type/descriptor/java/BooleanPrimitiveArrayJavaType.java @@ -16,6 +16,7 @@ import org.hibernate.SharedSessionContract; import org.hibernate.engine.jdbc.BinaryStream; import org.hibernate.engine.jdbc.internal.ArrayBackedBinaryStream; +import org.hibernate.internal.build.AllowReflection; import org.hibernate.internal.util.SerializationHelper; import org.hibernate.type.descriptor.WrapperOptions; @@ -24,6 +25,7 @@ * * @author Christian Beikov */ +@AllowReflection // Needed for arbitrary array wrapping/unwrapping public class BooleanPrimitiveArrayJavaType extends AbstractArrayJavaType { public static final BooleanPrimitiveArrayJavaType INSTANCE = new BooleanPrimitiveArrayJavaType(); diff --git a/hibernate-core/src/main/java/org/hibernate/type/descriptor/java/DoublePrimitiveArrayJavaType.java b/hibernate-core/src/main/java/org/hibernate/type/descriptor/java/DoublePrimitiveArrayJavaType.java index c598d009dbf6..f29c53fe8241 100644 --- a/hibernate-core/src/main/java/org/hibernate/type/descriptor/java/DoublePrimitiveArrayJavaType.java +++ b/hibernate-core/src/main/java/org/hibernate/type/descriptor/java/DoublePrimitiveArrayJavaType.java @@ -16,6 +16,7 @@ import org.hibernate.SharedSessionContract; import org.hibernate.engine.jdbc.BinaryStream; import org.hibernate.engine.jdbc.internal.ArrayBackedBinaryStream; +import org.hibernate.internal.build.AllowReflection; import org.hibernate.internal.util.SerializationHelper; import org.hibernate.type.descriptor.WrapperOptions; @@ -24,6 +25,7 @@ * * @author Christian Beikov */ +@AllowReflection // Needed for arbitrary array wrapping/unwrapping public class DoublePrimitiveArrayJavaType extends AbstractArrayJavaType { public static final DoublePrimitiveArrayJavaType INSTANCE = new DoublePrimitiveArrayJavaType(); diff --git a/hibernate-core/src/main/java/org/hibernate/type/descriptor/java/FloatPrimitiveArrayJavaType.java b/hibernate-core/src/main/java/org/hibernate/type/descriptor/java/FloatPrimitiveArrayJavaType.java index 442c09c387f2..db097bc95599 100644 --- a/hibernate-core/src/main/java/org/hibernate/type/descriptor/java/FloatPrimitiveArrayJavaType.java +++ b/hibernate-core/src/main/java/org/hibernate/type/descriptor/java/FloatPrimitiveArrayJavaType.java @@ -16,6 +16,7 @@ import org.hibernate.SharedSessionContract; import org.hibernate.engine.jdbc.BinaryStream; import org.hibernate.engine.jdbc.internal.ArrayBackedBinaryStream; +import org.hibernate.internal.build.AllowReflection; import org.hibernate.internal.util.SerializationHelper; import org.hibernate.type.descriptor.WrapperOptions; @@ -24,6 +25,7 @@ * * @author Christian Beikov */ +@AllowReflection // Needed for arbitrary array wrapping/unwrapping public class FloatPrimitiveArrayJavaType extends AbstractArrayJavaType { public static final FloatPrimitiveArrayJavaType INSTANCE = new FloatPrimitiveArrayJavaType(); diff --git a/hibernate-core/src/main/java/org/hibernate/type/descriptor/java/IntegerPrimitiveArrayJavaType.java b/hibernate-core/src/main/java/org/hibernate/type/descriptor/java/IntegerPrimitiveArrayJavaType.java index 60edc5ebe8f4..3dc831ee2b05 100644 --- a/hibernate-core/src/main/java/org/hibernate/type/descriptor/java/IntegerPrimitiveArrayJavaType.java +++ b/hibernate-core/src/main/java/org/hibernate/type/descriptor/java/IntegerPrimitiveArrayJavaType.java @@ -16,6 +16,7 @@ import org.hibernate.SharedSessionContract; import org.hibernate.engine.jdbc.BinaryStream; import org.hibernate.engine.jdbc.internal.ArrayBackedBinaryStream; +import org.hibernate.internal.build.AllowReflection; import org.hibernate.internal.util.SerializationHelper; import org.hibernate.type.descriptor.WrapperOptions; @@ -24,6 +25,7 @@ * * @author Christian Beikov */ +@AllowReflection // Needed for arbitrary array wrapping/unwrapping public class IntegerPrimitiveArrayJavaType extends AbstractArrayJavaType { public static final IntegerPrimitiveArrayJavaType INSTANCE = new IntegerPrimitiveArrayJavaType(); diff --git a/hibernate-core/src/main/java/org/hibernate/type/descriptor/java/LongPrimitiveArrayJavaType.java b/hibernate-core/src/main/java/org/hibernate/type/descriptor/java/LongPrimitiveArrayJavaType.java index d4423f9c0f4a..5369978dca61 100644 --- a/hibernate-core/src/main/java/org/hibernate/type/descriptor/java/LongPrimitiveArrayJavaType.java +++ b/hibernate-core/src/main/java/org/hibernate/type/descriptor/java/LongPrimitiveArrayJavaType.java @@ -16,6 +16,7 @@ import org.hibernate.SharedSessionContract; import org.hibernate.engine.jdbc.BinaryStream; import org.hibernate.engine.jdbc.internal.ArrayBackedBinaryStream; +import org.hibernate.internal.build.AllowReflection; import org.hibernate.internal.util.SerializationHelper; import org.hibernate.type.descriptor.WrapperOptions; @@ -24,6 +25,7 @@ * * @author Christian Beikov */ +@AllowReflection // Needed for arbitrary array wrapping/unwrapping public class LongPrimitiveArrayJavaType extends AbstractArrayJavaType { public static final LongPrimitiveArrayJavaType INSTANCE = new LongPrimitiveArrayJavaType(); diff --git a/hibernate-core/src/main/java/org/hibernate/type/descriptor/java/ShortPrimitiveArrayJavaType.java b/hibernate-core/src/main/java/org/hibernate/type/descriptor/java/ShortPrimitiveArrayJavaType.java index d0bf0b6731bc..981cfd87df0f 100644 --- a/hibernate-core/src/main/java/org/hibernate/type/descriptor/java/ShortPrimitiveArrayJavaType.java +++ b/hibernate-core/src/main/java/org/hibernate/type/descriptor/java/ShortPrimitiveArrayJavaType.java @@ -16,6 +16,7 @@ import org.hibernate.SharedSessionContract; import org.hibernate.engine.jdbc.BinaryStream; import org.hibernate.engine.jdbc.internal.ArrayBackedBinaryStream; +import org.hibernate.internal.build.AllowReflection; import org.hibernate.internal.util.SerializationHelper; import org.hibernate.type.descriptor.WrapperOptions; @@ -24,6 +25,7 @@ * * @author Christian Beikov */ +@AllowReflection // Needed for arbitrary array wrapping/unwrapping public class ShortPrimitiveArrayJavaType extends AbstractArrayJavaType { public static final ShortPrimitiveArrayJavaType INSTANCE = new ShortPrimitiveArrayJavaType(); diff --git a/hibernate-core/src/main/java/org/hibernate/type/descriptor/java/spi/BasicCollectionJavaType.java b/hibernate-core/src/main/java/org/hibernate/type/descriptor/java/spi/BasicCollectionJavaType.java index 88e32b23bd41..cbdef1177c54 100644 --- a/hibernate-core/src/main/java/org/hibernate/type/descriptor/java/spi/BasicCollectionJavaType.java +++ b/hibernate-core/src/main/java/org/hibernate/type/descriptor/java/spi/BasicCollectionJavaType.java @@ -21,6 +21,7 @@ import org.hibernate.dialect.Dialect; import org.hibernate.engine.jdbc.BinaryStream; import org.hibernate.engine.jdbc.internal.ArrayBackedBinaryStream; +import org.hibernate.internal.build.AllowReflection; import org.hibernate.internal.util.SerializationHelper; import org.hibernate.internal.util.collections.CollectionHelper; import org.hibernate.metamodel.CollectionClassification; @@ -46,6 +47,7 @@ * @author Christian Beikov */ @Incubating +@AllowReflection // Needed for arbitrary array wrapping/unwrapping public class BasicCollectionJavaType, E> extends AbstractJavaType implements BasicPluralJavaType { diff --git a/hibernate-core/src/main/java/org/hibernate/type/descriptor/jdbc/ArrayJdbcType.java b/hibernate-core/src/main/java/org/hibernate/type/descriptor/jdbc/ArrayJdbcType.java index 3bf37b59fb28..7581cf78625b 100644 --- a/hibernate-core/src/main/java/org/hibernate/type/descriptor/jdbc/ArrayJdbcType.java +++ b/hibernate-core/src/main/java/org/hibernate/type/descriptor/jdbc/ArrayJdbcType.java @@ -17,6 +17,7 @@ import org.hibernate.dialect.StructHelper; import org.hibernate.engine.jdbc.Size; import org.hibernate.engine.spi.SharedSessionContractImplementor; +import org.hibernate.internal.build.AllowReflection; import org.hibernate.metamodel.mapping.EmbeddableMappingType; import org.hibernate.type.BasicPluralType; import org.hibernate.type.descriptor.ValueBinder; @@ -40,6 +41,7 @@ * @author Christian Beikov * @author Jordan Gigov */ +@AllowReflection // See https://hibernate.atlassian.net/browse/HHH-16809 public class ArrayJdbcType implements JdbcType { private final JdbcType elementJdbcType; diff --git a/hibernate-core/src/main/java/org/hibernate/type/format/jaxb/JaxbXmlFormatMapper.java b/hibernate-core/src/main/java/org/hibernate/type/format/jaxb/JaxbXmlFormatMapper.java index cb567855cdcb..6a5becf99558 100644 --- a/hibernate-core/src/main/java/org/hibernate/type/format/jaxb/JaxbXmlFormatMapper.java +++ b/hibernate-core/src/main/java/org/hibernate/type/format/jaxb/JaxbXmlFormatMapper.java @@ -20,6 +20,7 @@ import jakarta.xml.bind.annotation.XmlElement; import org.hibernate.dialect.XmlHelper; +import org.hibernate.internal.build.AllowReflection; import org.hibernate.internal.util.ReflectHelper; import org.hibernate.internal.util.collections.CollectionHelper; import org.hibernate.sql.ast.spi.StringBuilderSqlAppender; @@ -70,6 +71,7 @@ public JaxbXmlFormatMapper(boolean legacyFormat) { } @Override + @AllowReflection public T fromString(CharSequence charSequence, JavaType javaType, WrapperOptions wrapperOptions) { if ( javaType.getJavaType() == String.class || javaType.getJavaType() == Object.class ) { return (T) charSequence.toString(); diff --git a/local-build-plugins/src/main/groovy/local.code-quality.gradle b/local-build-plugins/src/main/groovy/local.code-quality.gradle index 66308b2978e6..4b41bb60a14d 100644 --- a/local-build-plugins/src/main/groovy/local.code-quality.gradle +++ b/local-build-plugins/src/main/groovy/local.code-quality.gradle @@ -123,10 +123,14 @@ tasks.forbiddenApisMain { //bundledSignatures += ["jdk-system-out", "jdk-non-portable", "jdk-unsafe-${jdkVersions.baseline}"] bundledSignatures += ["jdk-system-out", "jdk-non-portable"] + signaturesFiles += rootProject.files('rules/forbidden-apis.txt') + ignoreSignaturesOfMissingClasses = true + suppressAnnotations += [ "org.hibernate.internal.build.AllowSysOut", "org.hibernate.internal.build.AllowPrintStacktrace", - "org.hibernate.internal.build.AllowNonPortable" + "org.hibernate.internal.build.AllowNonPortable", + "org.hibernate.internal.build.AllowReflection" ] } diff --git a/rules/forbidden-apis.txt b/rules/forbidden-apis.txt new file mode 100644 index 000000000000..01007e7b26c1 --- /dev/null +++ b/rules/forbidden-apis.txt @@ -0,0 +1,20 @@ +# SPDX-License-Identifier: LGPL-2.1-or-later +# Copyright Red Hat Inc. and Hibernate Authors + +# This file is a list of signatures to feed into Forbidden-API. +# It defines classes/methods to be avoided. +# See here for the syntax of this file: https://github.com/policeman-tools/forbidden-apis/wiki/SignaturesSyntax + +################################################################################################################ +# Reflection-related +@defaultMessage Use 'new Object[]' instead if possible. This forbidden method requires reflection and may not work in natively compiled applications. If you really must use this forbidden method, annotate the calling method with @AllowReflection. + +java.lang.reflect.Array#newInstance(java.lang.Class, int) +java.lang.reflect.Array#newInstance(java.lang.Class, int[]) +org.hibernate.internal.util.collections.ArrayHelper#newInstance(java.lang.Class, int) +org.hibernate.internal.util.collections.ArrayHelper#filledArray(java.lang.Object, java.lang.Class, int) +org.hibernate.internal.util.collections.ArrayHelper#join(java.lang.Object[], java.lang.Object[]) + +################################################################################################################ +# Misc -- put things here as a last resort, but if possible prefer adding a category above with an actionable message. +@defaultMessage Should not be used. \ No newline at end of file