diff --git a/build.gradle b/build.gradle index 6f424d8f44..9f33f33279 100644 --- a/build.gradle +++ b/build.gradle @@ -25,7 +25,7 @@ plugins { id 'org.hibernate.orm.database-service' apply false id 'biz.aQute.bnd' version '6.3.1' apply false - id 'org.checkerframework' version '0.6.34' + id 'org.checkerframework' version '0.6.40' id 'org.hibernate.orm.build.jdks' id 'io.github.gradle-nexus.publish-plugin' version '1.1.0' diff --git a/gradle/java-module.gradle b/gradle/java-module.gradle index edffd967d7..a840f90db0 100644 --- a/gradle/java-module.gradle +++ b/gradle/java-module.gradle @@ -477,6 +477,7 @@ tasks.withType(JavaCompile).configureEach { task -> } checkerFramework { + excludeTests = true checkers = [ 'org.checkerframework.checker.nullness.NullnessChecker' ] diff --git a/gradlew b/gradlew index 0adc8e1a53..1aa94a4269 100755 --- a/gradlew +++ b/gradlew @@ -145,7 +145,7 @@ if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then case $MAX_FD in #( max*) # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked. - # shellcheck disable=SC3045 + # shellcheck disable=SC2039,SC3045 MAX_FD=$( ulimit -H -n ) || warn "Could not query maximum file descriptor limit" esac @@ -153,7 +153,7 @@ if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then '' | soft) :;; #( *) # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked. - # shellcheck disable=SC3045 + # shellcheck disable=SC2039,SC3045 ulimit -n "$MAX_FD" || warn "Could not set maximum file descriptor limit to $MAX_FD" esac @@ -202,11 +202,11 @@ fi # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' -# Collect all arguments for the java command; -# * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of -# shell script including quotes and variable substitutions, so put them in -# double quotes to make sure that they get re-expanded; and -# * put everything else in single quotes, so that it's not re-expanded. +# Collect all arguments for the java command: +# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, +# and any embedded shellness will be escaped. +# * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be +# treated as '${Hostname}' itself on the command line. set -- \ "-Dorg.gradle.appname=$APP_BASE_NAME" \ diff --git a/hibernate-core/src/main/java/org/hibernate/engine/spi/ActionQueue.java b/hibernate-core/src/main/java/org/hibernate/engine/spi/ActionQueue.java index 62035ad4a1..332bcefa9b 100644 --- a/hibernate-core/src/main/java/org/hibernate/engine/spi/ActionQueue.java +++ b/hibernate-core/src/main/java/org/hibernate/engine/spi/ActionQueue.java @@ -57,6 +57,7 @@ import org.hibernate.type.EntityType; import org.hibernate.type.ForeignKeyDirection; import org.hibernate.type.Type; +import org.checkerframework.checker.nullness.qual.NonNull; import org.checkerframework.checker.nullness.qual.Nullable; import static org.hibernate.proxy.HibernateProxy.extractLazyInitializer; @@ -992,7 +993,7 @@ public class ActionQueue { protected SessionImplementor session; // Concurrency handling required when transaction completion process is dynamically registered // inside event listener (HHH-7478). - protected Queue processes = new ConcurrentLinkedQueue<>(); + protected ConcurrentLinkedQueue<@NonNull T> processes = new ConcurrentLinkedQueue<>(); private AbstractTransactionCompletionProcessQueue(SessionImplementor session) { this.session = session; @@ -1020,9 +1021,10 @@ public class ActionQueue { } public void beforeTransactionCompletion() { - while ( !processes.isEmpty() ) { + BeforeTransactionCompletionProcess process; + while ( ( process = processes.poll() ) != null ) { try { - processes.poll().doBeforeTransactionCompletion( session ); + process.doBeforeTransactionCompletion( session ); } catch (HibernateException he) { throw he; @@ -1050,9 +1052,10 @@ public class ActionQueue { } public void afterTransactionCompletion(boolean success) { - while ( !processes.isEmpty() ) { + AfterTransactionCompletionProcess process; + while ( ( process = processes.poll() ) != null ) { try { - processes.poll().doAfterTransactionCompletion( success, session ); + process.doAfterTransactionCompletion( success, session ); } catch (CacheException ce) { LOG.unableToReleaseCacheLock( ce ); diff --git a/hibernate-core/src/main/java/org/hibernate/type/descriptor/sql/internal/NativeEnumDdlTypeImpl.java b/hibernate-core/src/main/java/org/hibernate/type/descriptor/sql/internal/NativeEnumDdlTypeImpl.java index 12bba132ee..13c5737ecf 100644 --- a/hibernate-core/src/main/java/org/hibernate/type/descriptor/sql/internal/NativeEnumDdlTypeImpl.java +++ b/hibernate-core/src/main/java/org/hibernate/type/descriptor/sql/internal/NativeEnumDdlTypeImpl.java @@ -15,8 +15,6 @@ import org.hibernate.type.descriptor.jdbc.JdbcType; import org.hibernate.type.descriptor.sql.DdlType; import org.hibernate.type.descriptor.sql.spi.DdlTypeRegistry; -import org.checkerframework.checker.units.qual.N; - import static org.hibernate.type.SqlTypes.ENUM; /** diff --git a/tooling/metamodel-generator/src/main/java/org/hibernate/processor/ContainsAttributeTypeVisitor.java b/tooling/metamodel-generator/src/main/java/org/hibernate/processor/ContainsAttributeTypeVisitor.java index 412c062554..5f346bd831 100644 --- a/tooling/metamodel-generator/src/main/java/org/hibernate/processor/ContainsAttributeTypeVisitor.java +++ b/tooling/metamodel-generator/src/main/java/org/hibernate/processor/ContainsAttributeTypeVisitor.java @@ -14,6 +14,8 @@ import javax.lang.model.type.ExecutableType; import javax.lang.model.type.TypeMirror; import javax.lang.model.util.SimpleTypeVisitor8; +import org.hibernate.processor.util.NullnessUtil; + import static org.hibernate.processor.util.Constants.COLLECTIONS; import static org.hibernate.processor.util.StringUtil.isProperty; import static org.hibernate.processor.util.TypeUtils.getCollectionElementType; @@ -32,14 +34,13 @@ class ContainsAttributeTypeVisitor extends SimpleTypeVisitor8 @Override public Boolean visitDeclared(DeclaredType declaredType, Element element) { TypeElement returnedElement = (TypeElement) context.getTypeUtils().asElement(declaredType); - - final String returnTypeName = returnedElement.getQualifiedName().toString(); + final String returnTypeName = NullnessUtil.castNonNull( returnedElement ).getQualifiedName().toString(); final String collection = COLLECTIONS.get(returnTypeName); if (collection != null) { final TypeMirror collectionElementType = getCollectionElementType( declaredType, returnTypeName, null, context ); final Element collectionElement = context.getTypeUtils().asElement(collectionElementType); - if ( ElementKind.TYPE_PARAMETER == collectionElement.getKind() ) { + if ( ElementKind.TYPE_PARAMETER == NullnessUtil.castNonNull( collectionElement ).getKind() ) { return false; } returnedElement = (TypeElement) collectionElement; diff --git a/tooling/metamodel-generator/src/main/java/org/hibernate/processor/Context.java b/tooling/metamodel-generator/src/main/java/org/hibernate/processor/Context.java index c6932c82f0..95a65d14cb 100644 --- a/tooling/metamodel-generator/src/main/java/org/hibernate/processor/Context.java +++ b/tooling/metamodel-generator/src/main/java/org/hibernate/processor/Context.java @@ -13,6 +13,7 @@ import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; +import java.util.TreeSet; import javax.annotation.processing.ProcessingEnvironment; import javax.lang.model.element.AnnotationMirror; import javax.lang.model.element.AnnotationValue; @@ -504,6 +505,6 @@ public final class Context { } public void addEnumValue(String type, String value) { - enumTypesByValue.computeIfAbsent( value, s -> new HashSet<>() ).add( type ); + enumTypesByValue.computeIfAbsent( value, s -> new TreeSet<>() ).add( type ); } } diff --git a/tooling/metamodel-generator/src/main/java/org/hibernate/processor/HibernateProcessor.java b/tooling/metamodel-generator/src/main/java/org/hibernate/processor/HibernateProcessor.java index b727118379..0862baf7ed 100644 --- a/tooling/metamodel-generator/src/main/java/org/hibernate/processor/HibernateProcessor.java +++ b/tooling/metamodel-generator/src/main/java/org/hibernate/processor/HibernateProcessor.java @@ -704,7 +704,12 @@ public class HibernateProcessor extends AbstractProcessor { final ProcessingEnvironment processingEnvironment = context.getProcessingEnvironment(); context.getEntityNameMappings().forEach((entityName, className) -> { try (Writer writer = processingEnvironment.getFiler() - .createResource(StandardLocation.SOURCE_OUTPUT, ENTITY_INDEX, entityName) + .createResource( + StandardLocation.SOURCE_OUTPUT, + ENTITY_INDEX, + entityName, + processingEnvironment.getElementUtils().getTypeElement( className ) + ) .openWriter()) { writer.append(className); } @@ -715,8 +720,12 @@ public class HibernateProcessor extends AbstractProcessor { } }); context.getEnumTypesByValue().forEach((valueName, enumTypeNames) -> { - try (Writer writer = processingEnvironment.getFiler() - .createResource(StandardLocation.SOURCE_OUTPUT, ENTITY_INDEX, '.' + valueName) + try (Writer writer = processingEnvironment.getFiler().createResource( + StandardLocation.SOURCE_OUTPUT, + ENTITY_INDEX, + '.' + valueName, + processingEnvironment.getElementUtils().getTypeElement( enumTypeNames.iterator().next() ) + ) .openWriter()) { for (String enumTypeName : enumTypeNames) { writer.append(enumTypeName).append(" "); diff --git a/tooling/metamodel-generator/src/main/java/org/hibernate/processor/annotation/DataMetaAttributeGenerationVisitor.java b/tooling/metamodel-generator/src/main/java/org/hibernate/processor/annotation/DataMetaAttributeGenerationVisitor.java index e0873377b9..c28cf87ae8 100644 --- a/tooling/metamodel-generator/src/main/java/org/hibernate/processor/annotation/DataMetaAttributeGenerationVisitor.java +++ b/tooling/metamodel-generator/src/main/java/org/hibernate/processor/annotation/DataMetaAttributeGenerationVisitor.java @@ -9,6 +9,7 @@ package org.hibernate.processor.annotation; import org.checkerframework.checker.nullness.qual.Nullable; import org.hibernate.processor.Context; import org.hibernate.processor.util.Constants; +import org.hibernate.processor.util.NullnessUtil; import javax.lang.model.element.Element; import javax.lang.model.element.TypeElement; @@ -72,7 +73,7 @@ public class DataMetaAttributeGenerationVisitor extends SimpleTypeVisitor8<@Null public @Nullable DataAnnotationMetaAttribute visitDeclared(DeclaredType declaredType, Element element) { final TypeElement returnedElement = (TypeElement) typeUtils().asElement( declaredType ); // WARNING: .toString() is necessary here since Name equals does not compare to String - final String returnTypeName = returnedElement.getQualifiedName().toString(); + final String returnTypeName = NullnessUtil.castNonNull( returnedElement ).getQualifiedName().toString(); final String collection = Constants.COLLECTIONS.get( returnTypeName ); final String targetEntity = getTargetEntity( element.getAnnotationMirrors() ); if ( collection != null ) { diff --git a/tooling/metamodel-generator/src/main/java/org/hibernate/processor/annotation/MetaAttributeGenerationVisitor.java b/tooling/metamodel-generator/src/main/java/org/hibernate/processor/annotation/MetaAttributeGenerationVisitor.java index 5a03966567..abe3c35673 100644 --- a/tooling/metamodel-generator/src/main/java/org/hibernate/processor/annotation/MetaAttributeGenerationVisitor.java +++ b/tooling/metamodel-generator/src/main/java/org/hibernate/processor/annotation/MetaAttributeGenerationVisitor.java @@ -11,6 +11,7 @@ import org.hibernate.processor.Context; import org.hibernate.processor.util.AccessType; import org.hibernate.processor.util.AccessTypeInformation; import org.hibernate.processor.util.Constants; +import org.hibernate.processor.util.NullnessUtil; import javax.lang.model.element.AnnotationMirror; import javax.lang.model.element.Element; @@ -84,8 +85,9 @@ public class MetaAttributeGenerationVisitor extends SimpleTypeVisitor8<@Nullable @Override public @Nullable AnnotationMetaAttribute visitDeclared(DeclaredType declaredType, Element element) { final TypeElement returnedElement = (TypeElement) typeUtils().asElement( declaredType ); + assert returnedElement != null; // WARNING: .toString() is necessary here since Name equals does not compare to String - final String returnTypeName = returnedElement.getQualifiedName().toString(); + final String returnTypeName = NullnessUtil.castNonNull( returnedElement ).getQualifiedName().toString(); final String collection = Constants.COLLECTIONS.get( returnTypeName ); final String targetEntity = getTargetEntity( element.getAnnotationMirrors() ); if ( collection != null ) { @@ -109,7 +111,7 @@ public class MetaAttributeGenerationVisitor extends SimpleTypeVisitor8<@Nullable getCollectionElementType( declaredType, returnTypeName, explicitTargetEntity, context ); if ( collectionElementType.getKind() == TypeKind.DECLARED ) { final TypeElement collectionElement = (TypeElement) typeUtils().asElement( collectionElementType ); - setAccessType( collectionElementType, collectionElement ); + setAccessType( collectionElementType, NullnessUtil.castNonNull( collectionElement ) ); } } return createMetaAttribute( declaredType, element, collection, targetEntity ); diff --git a/tooling/metamodel-generator/src/main/java/org/hibernate/processor/util/BasicAttributeVisitor.java b/tooling/metamodel-generator/src/main/java/org/hibernate/processor/util/BasicAttributeVisitor.java index 1cc478cdad..c6b0269864 100644 --- a/tooling/metamodel-generator/src/main/java/org/hibernate/processor/util/BasicAttributeVisitor.java +++ b/tooling/metamodel-generator/src/main/java/org/hibernate/processor/util/BasicAttributeVisitor.java @@ -6,8 +6,8 @@ */ package org.hibernate.processor.util; +import org.hibernate.internal.util.NullnessUtil; import org.hibernate.processor.Context; -import org.hibernate.processor.util.Constants; import javax.lang.model.element.Element; import javax.lang.model.element.ElementKind; @@ -46,7 +46,7 @@ class BasicAttributeVisitor extends SimpleTypeVisitor8 { public Boolean visitArray(ArrayType arrayType, Element element) { final TypeElement componentElement = (TypeElement) context.getTypeUtils().asElement( arrayType.getComponentType() ); - return BASIC_ARRAY_TYPES.contains( componentElement.getQualifiedName().toString() ); + return BASIC_ARRAY_TYPES.contains( NullnessUtil.castNonNull( componentElement ).getQualifiedName().toString() ); } @Override diff --git a/tooling/metamodel-generator/src/main/java/org/hibernate/processor/util/TypeUtils.java b/tooling/metamodel-generator/src/main/java/org/hibernate/processor/util/TypeUtils.java index c272635525..724dd3c866 100644 --- a/tooling/metamodel-generator/src/main/java/org/hibernate/processor/util/TypeUtils.java +++ b/tooling/metamodel-generator/src/main/java/org/hibernate/processor/util/TypeUtils.java @@ -665,7 +665,7 @@ public final class TypeUtils { public @Nullable TypeElement visitDeclared(DeclaredType declaredType, Element element) { final TypeElement returnedElement = (TypeElement) context.getTypeUtils().asElement( declaredType ); - return containsAnnotation( returnedElement, EMBEDDABLE ) ? returnedElement : null; + return containsAnnotation( NullnessUtil.castNonNull( returnedElement ), EMBEDDABLE ) ? returnedElement : null; } @Override