Skip to content

#91 - Consider multi-project / multi-jar set up for hibernate-models #94

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Aug 26, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 13 additions & 9 deletions README.adoc
Original file line number Diff line number Diff line change
@@ -1,16 +1,11 @@
:fn-managed: footnote:[The application's domain and related classes]
== Hibernate models

Uses a mix of https://smallrye.io/jandex/[Jandex] and Java reflection to build the de-typed abstraction model of
classes and annotations referenced by an application's managed resources{fn-managed}.
Provides support for dealing with an application's managed resources{fn-managed} as a de-typed abstraction model
backed by one or more sources. Consumers can then access details from that abstraction model in a unified way,
regardless of the underlying source.

Consumers can then access details from that abstraction model in a unified way, regardless of the underlying
source. For classes which we are able to access from a Jandex index, this has the benefit that the classes are
not loaded into the ClassLoader which is important because once a classes is loaded into a ClassLoader, its
bytecode cannot be changed and run-time bytecode enhancement is not possible.

This work is intended to replace the https://github.com/hibernate/hibernate-commons-annotations[`hibernate-commons-annotation`] (HCANN)
library, which suffered from a number of shortcomings.
NOTE: This work replaces the https://github.com/hibernate/hibernate-commons-annotations[`hibernate-commons-annotation`] library, which suffered from a number of shortcomings.


=== Annotations
Expand All @@ -37,3 +32,12 @@ FieldDetails:: Think `java.lang.reflect.Field`
MethodDetails:: Think `java.lang.reflect.Method`
RecordComponentDetails:: Think `java.lang.reflect.RecordComponent`
ClassDetailsRegistry:: registry of `ClassDetails` references


=== Artifacts

hibernate-models:: The base support, using Java reflection as the backing source.
hibernate-models-jandex:: Optional support for using https://smallrye.io/jandex/[Jandex] as the backing source. Using
definitions from a Jandex index has the benefit that the classes are not loaded into the ClassLoader which can be important
in a few scenarios (e.g. retain the ability to enhance a class's bytecode).

123 changes: 14 additions & 109 deletions build.gradle
Original file line number Diff line number Diff line change
@@ -1,118 +1,23 @@
plugins {
id "java-library"

id "base-information"

id "checkstyle"
id "jacoco"

id "maven-publish"
id "io.github.gradle-nexus.publish-plugin" version "2.0.0"
id "publishing-config"
id "signing-config"
id "release-process"
id "io.github.gradle-nexus.publish-plugin"
}

dependencies {
implementation libs.jandex
implementation libs.logging

compileOnly libs.loggingAnnotations

annotationProcessor libs.loggingProcessor
annotationProcessor libs.logging
annotationProcessor libs.loggingAnnotations

testImplementation jakartaLibs.jpa
testImplementation testLibs.junit5Api
testImplementation testLibs.assertjCore

testRuntimeOnly testLibs.junit5Engine
testRuntimeOnly testLibs.log4j
}


// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Java handling
// OSSRH publishing
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

// To force the build produce the same byte-for-byte archives and hence make Hibernate Models build reproducible.
// See also https://docs.gradle.org/current/userguide/working_with_files.html#sec:reproducible_archives
tasks.withType(AbstractArchiveTask).configureEach {
preserveFileTimestamps = false
reproducibleFileOrder = true
}

java {
sourceCompatibility = jdks.versions.baseline.get() as int
targetCompatibility = jdks.versions.baseline.get() as int

withJavadocJar()
withSourcesJar()
}

test {
useJUnitPlatform()
}
String hibernatePublishUsername = project.hasProperty( 'hibernatePublishUsername' )
? project.property( 'hibernatePublishUsername' )
: null
String hibernatePublishPassword = project.hasProperty( 'hibernatePublishPassword' )
? project.property( 'hibernatePublishPassword' )
: null

// create a single "compile" task
tasks.register( "compile" ).configure {
dependsOn tasks.withType( JavaCompile )
}

tasks.withType( JavaCompile ).configureEach {javaCompile->
options.encoding = "UTF-8"
options.warnings false
}


// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Javadoc
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

tasks.named( "javadoc", Javadoc ) {
options {
use = true
encoding = "UTF-8"

addStringOption( "Xdoclint:none", "-quiet" )

tags(
"todo:X",
"apiNote:a:API Note:",
"implSpec:a:Implementation Specification:",
"implNote:a:Implementation Note:"
)
nexusPublishing {
repositories {
sonatype {
username = hibernatePublishUsername
password = hibernatePublishPassword
}
}
}


// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Checkstyle
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

checkstyle {
sourceSets = [ project.sourceSets.main ]
showViolations = false
}


// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// JaCoCo
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

def jacocoReportTask = tasks.named( "jacocoTestReport" ) {
dependsOn tasks.named( "test" )
}

jacocoTestReport {
reports {
xml.required = false
csv.required = false
html.outputLocation = layout.buildDirectory.dir( "jacocoHtml" )
}
}

tasks.named( "check" ) {
dependsOn jacocoReportTask
}
2 changes: 1 addition & 1 deletion buildSrc/src/main/groovy/base-information.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ group = "org.hibernate.models"
// Version handling
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

def versionFile = project.file( "version.txt" )
def versionFile = rootProject.file( "version.txt" )
def releaseVersion = determineVersion("releaseVersion", versionFile )
def developmentVersion = determineVersion("developmentVersion", versionFile)

Expand Down
103 changes: 103 additions & 0 deletions buildSrc/src/main/groovy/java-module.gradle
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
plugins {
id "base-information"
id "java-library"

id "checkstyle"
id "jacoco"
}

dependencies {
implementation libs.logging

compileOnly libs.loggingAnnotations

annotationProcessor libs.loggingProcessor
annotationProcessor libs.logging
annotationProcessor libs.loggingAnnotations

testImplementation jakartaLibs.jpa
testImplementation testLibs.junit5Api
testImplementation testLibs.assertjCore

testRuntimeOnly testLibs.junit5Engine
testRuntimeOnly testLibs.log4j
}


// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Java handling
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

java {
sourceCompatibility = jdks.versions.baseline.get() as int
targetCompatibility = jdks.versions.baseline.get() as int

withJavadocJar()
withSourcesJar()
}

test {
useJUnitPlatform()
}

// create a single "compile" task
tasks.register( "compile" ).configure {
dependsOn tasks.withType( JavaCompile )
}

tasks.withType( JavaCompile ).configureEach {javaCompile->
options.encoding = "UTF-8"
options.warnings false
}


// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Javadoc
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

tasks.named( "javadoc", Javadoc ) {
options {
use = true
encoding = "UTF-8"

addStringOption( "Xdoclint:none", "-quiet" )

tags(
"todo:X",
"apiNote:a:API Note:",
"implSpec:a:Implementation Specification:",
"implNote:a:Implementation Note:"
)
}
}


// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Checkstyle
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

checkstyle {
sourceSets = [ project.sourceSets.main ]
showViolations = false
}


// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// JaCoCo
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

def jacocoReportTask = tasks.named( "jacocoTestReport" ) {
dependsOn tasks.named( "test" )
}

jacocoTestReport {
reports {
xml.required = false
csv.required = false
html.outputLocation = layout.buildDirectory.dir( "jacocoHtml" )
}
}

tasks.named( "check" ) {
dependsOn jacocoReportTask
}
8 changes: 8 additions & 0 deletions buildSrc/src/main/groovy/published-java-module.gradle
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
plugins {
id "java-module"

id "maven-publish"
id "publishing-config"
id "signing-config"
id "release-process"
}
23 changes: 2 additions & 21 deletions buildSrc/src/main/groovy/publishing-config.gradle
Original file line number Diff line number Diff line change
@@ -1,18 +1,8 @@
plugins {
id "java-library"
id "io.github.gradle-nexus.publish-plugin"
id "java-module"
id "maven-publish"
}

// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// OSSRH publishing
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

String hibernatePublishUsername = project.hasProperty( 'hibernatePublishUsername' )
? project.property( 'hibernatePublishUsername' )
: null
String hibernatePublishPassword = project.hasProperty( 'hibernatePublishPassword' )
? project.property( 'hibernatePublishPassword' )
: null

publishing {
publications {
Expand Down Expand Up @@ -62,12 +52,3 @@ publishing {
}
}

nexusPublishing {
repositories {
sonatype {
username = hibernatePublishUsername
password = hibernatePublishPassword
}
}
}

13 changes: 13 additions & 0 deletions hibernate-models-jandex/build.gradle
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
plugins {
id "published-java-module"
}

description = "Jandex support for hibernate-models (isolated dependency)"

dependencies {
api project( ":hibernate-models" )

implementation libs.jandex

testImplementation project( ":hibernate-models-testing" )
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
* SPDX-License-Identifier: Apache-2.0
* Copyright: Red Hat Inc. and Hibernate Authors
*/
package org.hibernate.models.internal.jandex;
package org.hibernate.models.jandex.internal;

import java.lang.annotation.Annotation;
import java.util.Map;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,11 @@
* SPDX-License-Identifier: Apache-2.0
* Copyright: Red Hat Inc. and Hibernate Authors
*/
package org.hibernate.models.internal.jandex;
package org.hibernate.models.jandex.internal;

import org.hibernate.models.jandex.spi.JandexModelBuildingContext;
import org.hibernate.models.jandex.spi.JandexValueExtractor;
import org.hibernate.models.spi.SourceModelBuildingContext;
import org.hibernate.models.spi.JandexValueExtractor;

import org.jboss.jandex.AnnotationInstance;
import org.jboss.jandex.AnnotationValue;
Expand Down Expand Up @@ -38,6 +39,6 @@ protected AnnotationValue resolveAnnotationValue(
return explicitValue;
}

return annotation.valueWithDefault( buildingContext.getJandexIndex(), attributeName );
return annotation.valueWithDefault( buildingContext.as( JandexModelBuildingContext.class ).getJandexIndex(), attributeName );
}
}
Loading
Loading