hibernate-orm/gradle/java-module.gradle

608 lines
19 KiB
Groovy

/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* License: GNU Lesser General Public License (LGPL), version 2.1 or later
* See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html
*/
/**
* Support for modules that contain Java code
*/
buildscript {
repositories {
mavenCentral()
}
dependencies {
classpath 'de.thetaphi:forbiddenapis:3.0.1'
}
}
import de.thetaphi.forbiddenapis.gradle.CheckForbiddenApis
import org.apache.tools.ant.filters.ReplaceTokens
apply from: rootProject.file( 'gradle/libraries.gradle' )
apply from: rootProject.file( 'gradle/databases.gradle' )
apply plugin: 'java'
apply plugin: 'java-library'
apply plugin: 'biz.aQute.bnd.builder'
apply plugin: 'checkstyle'
apply plugin: 'build-dashboard'
apply plugin: 'project-report'
ext {
forbiddenAPITargetJDKCompatibility = '11'
}
if ( !project.description ) {
project.description = "The Hibernate ORM $project.name module"
}
// Attempt to leverage JetBrain's Gradle extension to automatically define
// `copyResourcesToIntelliJOutFolder` as a "build trigger" on import.
//
// However, see https://github.com/JetBrains/gradle-idea-ext-plugin/issues/8
apply plugin: 'org.jetbrains.gradle.plugin.idea-ext'
ext {
java9ModuleNameBase = project.name.startsWith( 'hibernate-' ) ? name.drop( 'hibernate-'.length() ): name
java9ModuleName = "org.hibernate.orm.$project.java9ModuleNameBase"
forbiddenAPITargetJDKCompatibility = '11'
}
if ( !project.description ) {
project.description = "The Hibernate ORM $project.name module"
}
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Configurations and Dependencies
configurations {
provided {
description = 'Non-exported compile-time dependencies.'
}
}
configurations.all*.exclude group: 'xml-apis', module: 'xml-apis'
dependencies {
implementation libraries.logging
compileOnly libraries.logging_annotations
// JUnit dependencies made up of:
// * JUnit 5
// * the Jupiter engine which runs JUnit 5 based tests
// * the "vintage" engine - which runs JUnit 3 and 4 based tests
testImplementation libraries.junit5_api
testImplementation libraries.junit5_jupiter
testImplementation libraries.junit5_params
testImplementation libraries.junit
testImplementation libraries.junit5_vintage
testImplementation libraries.byteman
testImplementation libraries.byteman_install
testImplementation libraries.byteman_bmunit
testRuntimeOnly libraries.log4j
testRuntimeOnly libraries.javassist
testRuntimeOnly libraries.byteBuddy
//Databases
testRuntimeOnly libraries.h2
testRuntimeOnly libraries.derby
testRuntimeOnly libraries.hsqldb
testRuntimeOnly libraries.postgresql
testRuntimeOnly libraries.mysql
testRuntimeOnly libraries.mariadb
testRuntimeOnly libraries.mssql
testRuntimeOnly libraries.informix
testRuntimeOnly libraries.hana
testRuntimeOnly libraries.cockroachdb
testRuntimeOnly libraries.oracle
// Since both the DB2 driver and HANA have a package "net.jpountz" we have to add dependencies conditionally
// This is due to the "no split-packages" requirement of Java 9+
if ( db.startsWith( 'db2' ) ) {
testRuntimeOnly libraries.db2
}
else if ( db.startsWith( 'hana' ) ) {
testRuntimeOnly libraries.hana
}
// Mac-specific
project.ext.toolsJar = file("${System.getProperty('java.home')}/../lib/tools.jar")
if ( project.toolsJar.exists() ) {
testCompileOnly files( project.toolsJar )
}
annotationProcessor libraries.logging_processor
annotationProcessor libraries.logging
annotationProcessor libraries.logging_annotations
}
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Compilation
tasks.withType( JavaCompile ) {
options.encoding = 'UTF-8'
}
if ( !gradle.ext.javaToolchainEnabled ) {
tasks.compileJava.configure {
sourceCompatibility = JavaVersion.toVersion( gradle.ext.javaVersions.main.release )
targetCompatibility = JavaVersion.toVersion( gradle.ext.javaVersions.main.release )
}
tasks.compileTestJava.configure {
sourceCompatibility = JavaVersion.toVersion( gradle.ext.javaVersions.test.release )
targetCompatibility = JavaVersion.toVersion( gradle.ext.javaVersions.test.release )
}
}
else {
// Configure generated bytecode
// "sourceCompatibility" is not supported with toolchains. We have to work around that limitation.
tasks.compileJava.configure {
if ( gradle.ext.javaVersions.main.compiler.asInt() < 9 ) {
options.compilerArgs << '-source'
options.compilerArgs << gradle.ext.javaVersions.main.release.toString()
options.compilerArgs << '-target'
options.compilerArgs << gradle.ext.javaVersions.main.release.toString()
} else {
options.release = gradle.ext.javaVersions.main.release.asInt()
// Needs add-opens because of https://github.com/gradle/gradle/issues/15538
options.forkOptions.jvmArgs.addAll( ["--add-opens", "jdk.compiler/com.sun.tools.javac.code=ALL-UNNAMED"] )
}
}
tasks.compileTestJava.configure {
if ( gradle.ext.javaVersions.test.compiler.asInt() < 9 ) {
options.compilerArgs << '-source'
options.compilerArgs << gradle.ext.javaVersions.test.release.toString()
options.compilerArgs << '-target'
options.compilerArgs << gradle.ext.javaVersions.test.release.toString()
} else {
options.release = gradle.ext.javaVersions.test.release.asInt()
// Needs add-opens because of https://github.com/gradle/gradle/issues/15538
options.forkOptions.jvmArgs.addAll( ["--add-opens", "jdk.compiler/com.sun.tools.javac.code=ALL-UNNAMED"] )
}
}
// Configure version of Java tools
java {
toolchain {
languageVersion = gradle.ext.javaVersions.main.compiler
}
}
tasks.compileTestJava {
javaCompiler = javaToolchains.compilerFor {
languageVersion = gradle.ext.javaVersions.test.compiler
}
}
// Configure JVM Options
tasks.withType( JavaCompile ).configureEach {
options.forkOptions.jvmArgs.addAll( getProperty( 'toolchain.compiler.jvmargs' ).toString().split( ' ' ) )
}
tasks.withType( Javadoc ).configureEach {
options.setJFlags( getProperty( 'toolchain.javadoc.jvmargs' ).toString().split( ' ' ).toList().findAll( { !it.isEmpty() } ) )
}
// Display version of Java tools
tasks.withType( JavaCompile ).configureEach {
doFirst {
logger.lifecycle "Compiling with '${javaCompiler.get().metadata.installationPath}'"
}
}
tasks.withType( Javadoc ).configureEach {
doFirst {
logger.lifecycle "Generating javadoc with '${javadocTool.get().metadata.installationPath}'"
}
}
}
task compile(dependsOn: [compileJava, processResources, compileTestJava, processTestResources] )
sourceSets.main {
compileClasspath += configurations.provided
}
convention.findPlugin( JavaPluginConvention.class ).sourceSets.each { sourceSet ->
JavaCompile javaCompileTask = project.tasks.findByName( sourceSet.compileJavaTaskName ) as JavaCompile
// NOTE : this aptDir stuff is needed until we can have IntelliJ run annotation processors for us
// which cannot happen until we can fold hibernate-testing back into hibernate-core/src/test
// which cannot happen until... ugh
File aptDir = file( "${buildDir}/generated-src/apt/${sourceSet.name}" )
sourceSet.allJava.srcDir( aptDir )
javaCompileTask.options.compilerArgs += [
"-nowarn",
"-encoding", "UTF-8",
"-s", "${aptDir.absolutePath}"
]
javaCompileTask.doFirst {
aptDir.mkdirs()
}
}
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// mac-specific stuff
final File toolsJar = file("${System.getProperty('java.home')}/../lib/tools.jar")
if ( ext.toolsJar.exists() ) {
dependencies{
testCompile files( toolsJar )
}
}
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Testing
if ( gradle.ext.javaToolchainEnabled ) {
tasks.test {
// Configure version of Java tools
javaLauncher = javaToolchains.launcherFor {
languageVersion = gradle.ext.javaVersions.test.launcher
}
// Configure JVM Options
jvmArgs( getProperty( 'toolchain.launcher.jvmargs' ).toString().split( ' ' ) )
// Display version of Java tools
doFirst {
logger.lifecycle "Testing with '${javaLauncher.get().metadata.installationPath}'"
}
}
}
tasks.withType( Test.class ).each { test ->
test.useJUnitPlatform()
if ( gradle.ext.javaVersions.test.launcher.asInt() >= 9 ) {
// Byteman needs this property to be set, https://developer.jboss.org/thread/274997
test.jvmArgs += ["-Djdk.attach.allowAttachSelf=true"]
}
test.jvmArgs += [
'-XX:+HeapDumpOnOutOfMemoryError',
"-XX:HeapDumpPath=${file( "${buildDir}/OOM-dump.hprof" ).absolutePath}",
'-XX:MetaspaceSize=256M'
]
test.maxHeapSize = '3G'
test.systemProperties['hibernate.test.validatefailureexpected'] = true
test.systemProperties += System.properties.findAll { it.key.startsWith( "hibernate." ) }
test.enableAssertions = true
if ( project.name != 'hibernate-testing' ) {
test.dependsOn ':hibernate-testing:test'
}
// todo (6.0) : temporarily include just the new tests so we can publish SNAPSHOTS for others to use
test.include 'org/hibernate/orm/test/**'
}
sourceSets {
test {
resources {
// add `src/test/java` as a test-resources dir
configure( srcDir('src/test/java') ) {
filter {
include '**/*.properties'
include '**/*.xml'
}
}
configure( srcDir('src/test/resources') ) {
filter {
include '*.properties'
include '*.xml'
include '**/*.properties'
include '**/*.xml'
}
}
}
}
}
processTestResources {
inputs.property( "db", db )
filter( ReplaceTokens, tokens: dbBundle[db] )
}
// Keep system properties in sync with gradle.properties!
test {
systemProperty 'user.language', 'en'
systemProperty 'user.country', 'US'
systemProperty 'user.timezone', 'UTC'
systemProperty 'file.encoding', 'UTF-8'
// Needed for AdoptOpenJDK on alpine? The problem is similar to this: https://github.com/mockito/mockito/issues/978
jvmArgs '-XX:+StartAttachListener'
}
// Enable the experimental features of ByteBuddy with JDK 18+
test {
if ( gradle.ext.javaVersions.test.release.asInt() >= 18 ) {
logger.warn( "The version of Java bytecode that will be tested is not supported by Bytebuddy by default. " +
" Setting 'net.bytebuddy.experimental=true'." )
systemProperty 'net.bytebuddy.experimental', true
}
}
test {
if ( project.findProperty( 'log-test-progress' )?.toString()?.toBoolean() ) {
// Log a statement for each test.
// Used in the Travis build so that Travis doesn't end up panicking because there's no output for a long time.
testLogging {
events "passed", "skipped", "failed"
}
}
}
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Artifacts (jar, sources, javadoc)
ext {
java9ModuleNameBase = project.name.startsWith( 'hibernate-' ) ? name.drop( 'hibernate-'.length() ): name
java9ModuleName = "org.hibernate.orm.$project.java9ModuleNameBase"
}
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Jar
jar {
manifest {
attributes(
// Basic JAR manifest attributes
'Specification-Title': project.name,
'Specification-Version': project.version,
'Specification-Vendor': 'Hibernate.org',
'Implementation-Title': project.name,
'Implementation-Version': project.version,
'Implementation-Vendor': 'Hibernate.org',
'Implementation-Vendor-Id': 'org.hibernate',
'Implementation-Url': 'http://hibernate.org/orm',
// Java 9 module name
'Automatic-Module-Name': project.java9ModuleName,
// Hibernate-specific JAR manifest attributes
'Hibernate-VersionFamily': project.ormVersion.family,
'Hibernate-JpaVersion': project.jpaVersion.name,
// BND Plugin instructions (for OSGi):
'Bundle-Name': project.name,
'Bundle-SymbolicName': project.java9ModuleName,
'Bundle-Vendor': 'Hibernate.org',
'Bundle-DocURL': "http://www.hibernate.org/orm/${project.ormVersion.family}",
// This is overridden in some sub-projects
'Import-Package': [
// Temporarily support JTA 1.1 -- Karaf and other frameworks still
// use it. Without this, the plugin generates [1.2,2).
'javax.transaction;version="[1.1,2)"',
// Also import every package referenced in the code
// (note that '*' is resolved at build time to a list of packages)
'*'
].join( ',' ),
'-exportcontents': "*;version=${project.version}"
)
}
}
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// sources
task sourcesJar(type: Jar) {
from project.sourceSets.main.allSource
manifest {
attributes(
// Basic JAR manifest attributes
'Specification-Title': project.name,
'Specification-Version': project.version,
'Specification-Vendor': 'Hibernate.org',
'Implementation-Title': project.name,
'Implementation-Version': project.version,
'Implementation-Vendor': 'Hibernate.org',
'Implementation-Vendor-Id': 'org.hibernate',
'Implementation-Url': 'http://hibernate.org/orm',
// Hibernate-specific JAR manifest attributes
'Hibernate-VersionFamily': project.ormVersion.family,
'Hibernate-JpaVersion': project.jpaVersion.name
)
}
archiveClassifier.set( 'sources' )
}
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Javadoc
apply from: rootProject.file( 'gradle/javadoc.gradle' )
javadoc {
doFirst {
// ordering problems if we try to do this during config phase :(
classpath += project.sourceSets.main.output.classesDirs + project.sourceSets.main.compileClasspath + project.configurations.provided
}
}
task javadocJar(type: Jar) {
from project.tasks.javadoc.outputs
manifest {
attributes(
// Basic JAR manifest attributes
'Specification-Title': project.name,
'Specification-Version': project.version,
'Specification-Vendor': 'Hibernate.org',
'Implementation-Title': project.name,
'Implementation-Version': project.version,
'Implementation-Vendor': 'Hibernate.org',
'Implementation-Vendor-Id': 'org.hibernate',
'Implementation-Url': 'http://hibernate.org/orm',
// Hibernate-specific JAR manifest attributes
'Hibernate-VersionFamily': project.ormVersion.family,
'Hibernate-JpaVersion': project.jpaVersion.name
)
}
archiveClassifier.set( 'javadoc' )
}
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// IDE
//idea {
// module {
// jdkName = project.sourceCompatibility
//
// excludeDirs = [file( ".gradle" )]
// excludeDirs += file( "$buildDir/classes" )
// excludeDirs += file( "$buildDir/bundles" )
// excludeDirs += file( "$buildDir/packages" )
// excludeDirs += file( "$buildDir/dependency-cache" )
// excludeDirs += file( "$buildDir/libs" )
// excludeDirs += file( "$buildDir/reports" )
// excludeDirs += file( "$buildDir/test-results" )
// excludeDirs += file( "$buildDir/tmp" )
// excludeDirs += file( "$buildDir/matrix" )
// excludeDirs += file( "$buildDir/resources" )
//
// downloadSources = true
// scopes.PROVIDED.plus += [configurations.provided]
// }
//}
//
/*
The latest versions of IntelliJ copy and use the test resources into out/test/resources
this occurs before the placeholder in the test config file are substituted
with the testing values.
This behaviour prevents the execution of the hibernate tests from inside the IDE.
A solution is to enable the 'After Build' Execution of the copyResourcesToIntelliJOutFolder task
from the 'Gradle project' IntelliJ tool window ( The task can be found under hibernate-orm > Task > other)
*/
task copyResourcesToIntelliJOutFolder(type: Task, dependsOn: project.tasks.processTestResources) {
doLast {
copy {
from "$buildDir/resources/test"
into 'out/test/resources'
}
}
}
//
//
//
//eclipse {
// jdt {
// sourceCompatibility = project.sourceCompatibility
// targetCompatibility = project.targetCompatibility
// }
// classpath {
// plusConfigurations.add( configurations.provided )
// }
//}
//
//// eclipseClasspath will not add sources to classpath unless the dirs actually exist.
//// TODO: Eclipse's annotation processor handling is also fairly stupid (and completely lacks in the
//// Gradle plugin). For now, just compile first in order to get the logging classes.
//eclipseClasspath.dependsOn compile
/*
Use this task to set the current DB in a given module.
> gradlew sDB -Pdb=mysql
Afterward, you can run any test from the IDE against that particular DB.
*/
task setDataBase dependsOn( processTestResources, copyResourcesToIntelliJOutFolder ) {
println( 'Setting current database to ' + db )
}
copyResourcesToIntelliJOutFolder.mustRunAfter processTestResources
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Report configs
checkstyle {
sourceSets = [ project.sourceSets.main ]
configFile = rootProject.file( 'shared/config/checkstyle/checkstyle.xml' )
showViolations = false
}
// exclude generated java sources - by explicitly setting the base source dir
checkstyleMain.source = 'src/main/java'
// define a second checkstyle task for checking non-fatal violations
task nonFatalCheckstyle(type:Checkstyle) {
source = project.sourceSets.main.java
classpath = project.configurations.checkstyle
showViolations = false
configFile = rootProject.file( 'shared/config/checkstyle/checkstyle-non-fatal.xml' )
}
// because cfg package is a mess mainly from annotation stuff
checkstyleMain.exclude '**/org/hibernate/cfg/**'
checkstyleMain.exclude '**/org/hibernate/cfg/*'
task forbiddenApisSystemOut(type: CheckForbiddenApis, dependsOn: compileJava) {
classesDirs = project.sourceSets.main.output.classesDirs
classpath = project.sourceSets.main.compileClasspath + project.sourceSets.main.runtimeClasspath
targetCompatibility = project.forbiddenAPITargetJDKCompatibility
bundledSignatures += 'jdk-system-out'
suppressAnnotations += ['org.hibernate.internal.build.AllowSysOut', 'org.hibernate.internal.build.AllowPrintStacktrace']
// This slows down the checks a little, but is necessary to avoid the gradle deamon holding on
// to class definitions loaded previously - even possibly in a previous build.
disableClassloadingCache = true
}
task forbiddenApisUnsafe(type: CheckForbiddenApis, dependsOn: compileJava) {
classesDirs = project.sourceSets.main.output.classesDirs
classpath = project.sourceSets.main.compileClasspath + project.sourceSets.main.runtimeClasspath
targetCompatibility = project.forbiddenAPITargetJDKCompatibility
bundledSignatures += "jdk-unsafe-${gradle.ext.baselineJavaVersion}".toString()
// unfortunately we currently have many uses of default Locale implicitly (~370) which need to be fixed
// before we can fully enabled this check
//
// No idea how findbugs was missing these b4
ignoreFailures = true
// This slows down the checks a little, but is necessary to avoid the gradle deamon holding on
// to class definitions loaded previously - even possibly in a previous build.
disableClassloadingCache = true
}
task forbiddenApisNonPortable(type: CheckForbiddenApis, dependsOn: compileJava) {
classesDirs = project.sourceSets.main.output.classesDirs
classpath = project.sourceSets.main.compileClasspath + project.sourceSets.main.runtimeClasspath
targetCompatibility = project.forbiddenAPITargetJDKCompatibility
bundledSignatures += 'jdk-non-portable'
// This slows down the checks a little, but is necessary to avoid the gradle deamon holding on
// to class definitions loaded previously - even possibly in a previous build.
disableClassloadingCache = true
}
task forbiddenApis
project.tasks.withType( CheckForbiddenApis ).each { task -> forbiddenApis.finalizedBy task }
project.tasks.check.finalizedBy forbiddenApis