Skip to content
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

feat(jpms): add module-info.java descriptors (w/build upgrades) #5

Draft
wants to merge 15 commits into
base: master
Choose a base branch
from
Draft
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
10 changes: 4 additions & 6 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,15 +11,13 @@ on:
jobs:
build:
runs-on: ubuntu-latest
strategy:
matrix:
java: [ '8', '11' ]
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v4
- name: Set up JDK
uses: actions/setup-java@v1
uses: actions/setup-java@v4
with:
java-version: ${{ matrix.java }}
java-version: 21
distribution: adopt
- name: print Java version
run: java -version
- name: Build with Gradle
Expand Down
85 changes: 69 additions & 16 deletions api/build.gradle
Original file line number Diff line number Diff line change
@@ -1,32 +1,85 @@
description = "reactive-streams"
def jdkFlow = false
try {
Class.forName("java.util.concurrent.Flow")
jdkFlow = true
} catch (ClassNotFoundException cnfe) {

}

sourceSets {
main {
java {
if (jdkFlow)
srcDirs = ['src/main/java', 'src/main/java9']
else
srcDirs = ['src/main/java']
srcDirs = ['src/main/java']
}
}
java9 {
java {
srcDirs = ['src/main/java', 'src/main/java9']
}
}
}

def jpmsMinimumTarget = 9
def javaMaximumTarget = 21
def javaTestTargets = [11, 17, javaMaximumTarget]

configurations {
mrjarArtifact
}

jar {
bnd ('Bundle-Name': 'reactive-streams-jvm',
into('META-INF/versions/9') {
from(sourceSets.java9.output) {
include '**/FlowAdapters*'
include '**/module-info.class'
}
}

bundle {
bnd('Bundle-Name': 'reactive-streams-jvm',
'Bundle-Vendor': 'Reactive Streams SIG',
'Bundle-Description': 'Reactive Streams API',
'Bundle-DocURL': 'http://reactive-streams.org',
'Bundle-Version': project.version,
'Export-Package': 'org.reactivestreams.*',
'Automatic-Module-Name': 'org.reactivestreams',
'Bundle-SymbolicName': 'org.reactivestreams.reactive-streams'
)
'Export-Package': 'org.reactivestreams.*,!META-INF.*',
'Multi-Release': true,
'Bundle-SymbolicName': 'org.reactivestreams.reactive-streams',
'-fixupmessages': '^Classes found in the wrong directory: .*'
)
}
}

artifacts { mrjarArtifact jar }

compileJava9Java {
group = "build"
description = "Compile Java 9 classes for MR JAR"

sourceCompatibility = jpmsMinimumTarget
targetCompatibility = jpmsMinimumTarget
}

tasks.register('validateModularJar', Exec) {
dependsOn jar
inputs.file jar.outputs.files.asPath

executable = "jar"
args = ['--describe-module', '--file', jar.outputs.files.asPath]
}

javaTestTargets.each { majorVersion ->
def validateModularJar = tasks.register("validateModularJarJdk$majorVersion", Exec) {
description = "Validates the modular JAR on JDK $majorVersion"
group = LifecycleBasePlugin.VERIFICATION_GROUP

def javaLauncher = javaToolchains.launcherFor {
languageVersion = JavaLanguageVersion.of(majorVersion)
}

dependsOn jar
inputs.file jar.outputs.files.asPath

// ugly, but it accesses the `jar` executable which is peer to the resolved `java` launcher
executable = javaLauncher.get().executablePath.asFile.parentFile.toPath().resolve("jar").toFile()
args = ['--describe-module', '--file', jar.outputs.files.asPath, "--release", "$majorVersion"]
}
tasks.named("check").configure { dependsOn(validateModularJar) }
}

tasks.check {
finalizedBy validateModularJar
}
4 changes: 4 additions & 0 deletions api/gradle.lockfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
# This is a Gradle generated file for dependency locking.
# Manual edits can break the build and are not advised.
# This file is expected to be part of source control.
empty=annotationProcessor,baseline,compileClasspath,java9AnnotationProcessor,java9CompileClasspath,java9RuntimeClasspath,mrjarArtifact,runtimeClasspath,testAnnotationProcessor,testCompileClasspath,testRuntimeClasspath
10 changes: 10 additions & 0 deletions api/src/main/java9/module-info.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
/***************************************************
* Licensed under MIT No Attribution (SPDX: MIT-0) *
***************************************************/

/**
* Reactive Streams
*/
module org.reactivestreams {
exports org.reactivestreams;
}
179 changes: 94 additions & 85 deletions build.gradle
Original file line number Diff line number Diff line change
@@ -1,25 +1,38 @@
buildscript {
repositories {
jcenter()
mavenCentral()
maven {
url "https://plugins.gradle.org/m2/"
}
}
dependencies {
classpath "biz.aQute.bnd:biz.aQute.bnd.gradle:4.3.1"
}
plugins {
alias(libs.plugins.bnd) apply false
alias(libs.plugins.testlogger) apply false
}

def projectVersion = properties["releaseVersion"] ?: "1.0.4"
def sonatypeRepo = 'https://oss.sonatype.org/service/local/staging/deploy/maven2/'
def sonatypeSnapshots = 'https://oss.sonatype.org/content/repositories/snapshots/'

def distributionRepository = properties["distributionRepository"] ?: sonatypeRepo
def snapshotsRepository = properties["snapshotsRepository"] ?: sonatypeSnapshots

def baselineToolchain = properties["javaBaseline"] ?: libs.versions.java.baseline.get()

subprojects {
apply plugin: "java-library"
apply plugin: 'biz.aQute.bnd.builder'
apply plugin: libs.plugins.bnd.get().pluginId
apply plugin: libs.plugins.testlogger.get().pluginId

group = "org.reactivestreams"
version = "1.0.4"
version = projectVersion

sourceCompatibility = 1.6
targetCompatibility = 1.6
dependencyLocking {
lockAllConfigurations()
}

tasks.compileJava {
group = "build"
description = "Compile Java 1.6 classes"
sourceCompatibility = 1.6
targetCompatibility = 1.6
javaCompiler = javaToolchains.compilerFor {
languageVersion = JavaLanguageVersion.of(baselineToolchain)
}
}

tasks.withType(JavaCompile) {
configure(options) {
Expand All @@ -38,11 +51,14 @@ subprojects {
}
}

tasks.withType(Test) {
testLogging {
exceptionFormat "full"
events "failed", "started", "standard_out", "standard_error"
}
testlogger {
theme 'mocha-parallel'
showExceptions true
showStackTraces true
showPassed true
showSkipped false
showFailed true
showStandardStreams false
}

repositories {
Expand All @@ -53,100 +69,93 @@ subprojects {
"reactive-streams-tck",
"reactive-streams-tck-flow",
"reactive-streams-examples"]) {
apply plugin: "maven"
apply plugin: "signing"
apply plugin: "publishing"
apply plugin: "maven-publish"

signing {
sign configurations.archives
required { gradle.taskGraph.hasTask(uploadArchives) }
required { gradle.taskGraph.hasTask("publish") }
}

task sourcesJar(type: Jar) {
classifier "sources"
archiveClassifier = "sources"
from sourceSets.main.allSource
}

task javadocJar(type: Jar) {
classifier "javadoc"
archiveClassifier = "javadoc"
from javadoc
}

publishing {
publications {
mavenJava(MavenPublication) {
from components.java

pom {
url = "https://www.reactive-streams.org/"
name = "reactive-streams"
description = "A Protocol for Asynchronous Non-Blocking Data Sequence"
inceptionYear = "2014"

scm {
url = "[email protected]:reactive-streams/reactive-streams.git"
connection = "scm:git:[email protected]:reactive-streams/reactive-streams.git"
}

licenses {
license {
name = "MIT-0"
url = "https://spdx.org/licenses/MIT-0.html"
distribution = "repo"
}
}

developers {
developer {
id = "reactive-streams-sig"
name = "Reactive Streams SIG"
url = "https://www.reactive-streams.org/"
}
}
}
}
}
repositories {
mavenLocal()

gradle.taskGraph.whenReady { taskGraph ->
if (taskGraph.hasTask("publish")) {
def userProp = "sonatypeOssUsername"
def passwordProp = "sonatypeOssPassword"
def user = project.properties[userProp]
def password = project.properties[passwordProp]

if ((user == null || password == null) && distributionRepository == sonatypeRepo) {
throw new InvalidUserDataException(
"Cannot perform $uploadArchives.path due to missing credentials.\n" +
"Run with command line args `-P$userProp=«username» -P$passwordProp=«password»` or add these properties to $gradle.gradleUserHomeDir/gradle.properties.\n")
}

repository(url: distributionRepository) {
authentication(userName: user, password: password)
}
if (sonatypeSnapshots != "") {
snapshotRepository(url: snapshotsRepository) {
authentication(userName: user, password: password)
}
}
}
}
}
}

artifacts {
archives sourcesJar, javadocJar
}
signing {

uploadArchives {
repositories {
mavenDeployer {
gradle.taskGraph.whenReady { taskGraph ->
if (taskGraph.hasTask(uploadArchives)) {
def userProp = "sonatypeOssUsername"
def passwordProp = "sonatypeOssPassword"
def user = project.properties[userProp]
def password = project.properties[passwordProp]

if (user == null || password == null) {
throw new InvalidUserDataException(
"Cannot perform $uploadArchives.path due to missing credentials.\n" +
"Run with command line args `-P$userProp=«username» -P$passwordProp=«password»` or add these properties to $gradle.gradleUserHomeDir/gradle.properties.\n")
}

repository(url: "https://oss.sonatype.org/service/local/staging/deploy/maven2/") {
authentication(userName: user, password: password)
}
snapshotRepository(url: "https://oss.sonatype.org/content/repositories/snapshots/") {
authentication(userName: user, password: password)
}
}
}
}
}
}

tasks.withType(Upload) {
repositories.withType(MavenResolver) {
it.beforeDeployment { signing.signPom(it) }
it.pom.whenConfigured { pom ->
pom.project {
url "http://www.reactive-streams.org/"
name "reactive-streams"
description "A Protocol for Asynchronous Non-Blocking Data Sequence"
inceptionYear "2014"

scm {
url "[email protected]:reactive-streams/reactive-streams.git"
connection "scm:git:[email protected]:reactive-streams/reactive-streams.git"
}

licenses {
license {
name "MIT-0"
url "https://spdx.org/licenses/MIT-0.html"
distribution "repo"
}
}

developers {
developer {
id "reactive-streams-sig"
name "Reactive Streams SIG"
url "http://www.reactive-streams.org/"
}
}
}
}
}
}
} else {
uploadArchives.enabled = false
Expand Down
6 changes: 4 additions & 2 deletions examples/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,17 @@ dependencies {
}

jar {
bnd ('Bundle-Name': 'reactive-streams-jvm',
bundle {
bnd('Bundle-Name': 'reactive-streams-jvm',
'Bundle-Vendor': 'Reactive Streams SIG',
'Bundle-Description': 'Reactive Streams Examples',
'Bundle-DocURL': 'http://reactive-streams.org',
'Bundle-Version': project.version,
'Export-Package': 'org.reactivestreams.example.*',
'Automatic-Module-Name': 'org.reactivestreams.examples',
'Bundle-SymbolicName': 'org.reactivestreams.examples'
)
)
}
}

test.useTestNG()
Loading