Skip to content

Commit

Permalink
[#711] make picocli a modular multi-release jar
Browse files Browse the repository at this point in the history
  • Loading branch information
remkop committed May 31, 2019
1 parent 64cb2a1 commit d127560
Show file tree
Hide file tree
Showing 4 changed files with 43 additions and 116 deletions.
15 changes: 15 additions & 0 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,16 @@ version "$projectVersion"
buildscript {
repositories {
jcenter()
maven {
url "https://plugins.gradle.org/m2/"
}
}

dependencies {
classpath "org.asciidoctor:asciidoctor-gradle-plugin:$asciidoctorGradlePluginVersion"
classpath 'org.asciidoctor:asciidoctorj-pdf:1.5.0-alpha.15'
classpath "com.jfrog.bintray.gradle:gradle-bintray-plugin:$gradleBintrayPluginVersion"
classpath "gradle.plugin.org.beryx:badass-jar:1.1.3"
}
}

Expand All @@ -19,6 +23,7 @@ apply plugin: 'distribution'
apply plugin: 'maven-publish'
apply plugin: 'com.jfrog.bintray'


allprojects {
apply plugin: 'groovy'
apply plugin: 'java'
Expand Down Expand Up @@ -144,6 +149,16 @@ allprojects {
}
}

dependencies {
compile project(':picocli-jpms-module')
}
task copyModuleInfo(dependsOn: classes, type: Copy) {
dependsOn(':picocli-jpms-module:jar') // the jar task in picocli-jpms-module writes ${project(':picocli-jpms-module').buildDir}/classes/java/main/META-INF/versions/9/module-info.class
from("${project(':picocli-jpms-module').buildDir}/classes/java/main")
into "${buildDir}/classes/java/main"
}
jar.dependsOn(copyModuleInfo)

jar {
manifest {
attributes 'Specification-Title' : 'picocli',
Expand Down
25 changes: 6 additions & 19 deletions picocli-jpms-module/README.md
Original file line number Diff line number Diff line change
@@ -1,25 +1,12 @@
<p align="center"><img src="https://picocli.info/images/logo/horizontal-400x150.png" alt="picocli" height="150px"></p>

# Picocli JPMS Module

This subproject generates a [modular jar](https://openjdk.java.net/projects/jigsaw/spec/sotms/#module-artifacts) `picocli-jpms-module-${version}.jar` for applications that want to use picocli while taking full advantage of the Java Platform Module System (JPMS) introduced in Java 9.

This jar is generated in addition to the `picocli-${version}.jar` artifact. Starting from picocli 4.0, `picocli-${version}.jar` will no longer be an [automatic module](https://openjdk.java.net/projects/jigsaw/spec/sotms/#automatic-modules).

## Contents of picocli-jpms-module

* a `module-info.class` in the root of the jar.
* the classes in the `picocli` package.
* excludes (does not contain) any classes in the `picocli.groovy` package, so this module has no dependency on Groovy.

We considered making the `picocli-jpms-module` artifact a
modular multi-release jar with the `module-info.class` file located in `META-INF/versions/9`,
in the hope that this would avoid problems for some older tools,
which incorrectly process the module descriptor as if it were a normal Java class.

However, putting the `module-info.class` file in `META-INF/versions/9` seems to have its own problems, as discussed [here](https:/remkop/picocli/issues/674).
This subproject does not produce any artifacts,
but generates a `picocli-jpms-module/build/classes/java/main/META-INF/versions/9/module-info.class` file,
for inclusion in the main `picocli-${version}.jar` artifact.

Starting from picocli 4.0, `picocli-${version}.jar` will no longer be an [automatic module](https://openjdk.java.net/projects/jigsaw/spec/sotms/#automatic-modules),
but will be a [modular multi-release jar](https://openjdk.java.net/jeps/238#Modular-multi-release-JAR-files).

I'm open to changing this, based on community feedback. Let us know what works or does not work for you!

# Using picocli with Java 9 modules

Expand Down
100 changes: 3 additions & 97 deletions picocli-jpms-module/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -11,35 +11,17 @@ buildscript {

plugins {
id 'java'
id 'distribution'
id 'maven-publish'
id 'com.jfrog.bintray'
id 'java-library'
//id 'org.beryx.jar' version '1.1.3'
}

apply plugin: "org.beryx.jar"

group 'info.picocli'
description 'Picocli JPMS module: a modular jar for applications that want to use picocli while taking full advantage of the Java Platform Module System (JPMS) introduced in Java 9'
description 'Picocli JPMS module: compiles the module-info.class to make the picocli jar a modular jar'
version "$projectVersion"
ext.moduleName = 'info.picocli'
sourceCompatibility = JavaVersion.VERSION_1_8
targetCompatibility = JavaVersion.VERSION_1_8

dependencies {
compile rootProject
compile project(':picocli-codegen')
}

task copyRootProjectClasses(dependsOn: classes, type: Copy) {
from("${rootProject.buildDir}/classes/java/main") {
exclude '**/groovy'
}
from("${rootProject.buildDir}/resources/main")
into "${buildDir}/classes/java/main"
}
jar.dependsOn(copyRootProjectClasses)

compileJava {
inputs.property("moduleName", moduleName)
Expand All @@ -53,83 +35,7 @@ compileJava {
}
}

test {
// Excluding unit tests, should have been generated already with the root project.
exclude 'picocli'
}

jar {
manifest {
attributes 'Specification-Title' : 'picocli-jpms-module',
'Specification-Vendor' : 'Remko Popma',
'Specification-Version' : version,
'Implementation-Title' : 'picocli-jpms-module',
'Implementation-Vendor' : 'Remko Popma',
'Implementation-Version': version,
'Main-Class' : 'picocli.AutoComplete'
}
multiRelease = false
}


ext {
bintrayPackage = 'picocli-jpms-module'
bintrayWebsiteUrl = 'https:/remkop/picocli/tree/master/picocli-jpms-module'
bintrayLabels = ['jpms', 'module', 'java9', 'picocli']
}
bintray {
user = bintrayUsername
key = bintrayApiKey
publications = ['MyPublication']
dryRun = bintrayDryRun //[Default: false] Whether to run this as dry-run, without deploying
publish = bintrayPublish //[Default: false] Whether version should be auto published after an upload
override = bintrayOverride //[Default: false] Whether to override version artifacts already published
//Package configuration. The plugin will use the repo and name properties to check if the package already exists. In that case, there's no need to configure the other package properties (like userOrg, desc, etc).
pkg {
repo = 'picocli'
name = bintrayPackage
userOrg = 'remkop'
licenses = ['Apache-2.0']
desc = description
websiteUrl = bintrayWebsiteUrl
issueTrackerUrl = 'https:/remkop/picocli/issues'
vcsUrl = 'https:/remkop/picocli.git'
labels = bintrayLabels
publicDownloadNumbers = false
version {
name = "$projectVersion"
desc = description
released = new Date()
vcsTag = "v$projectVersion"
mavenCentralSync {
sync = mavenOssSync //[Default: true] Determines whether to sync the version to Maven Central.
user = mavenOssUser //OSS user token: mandatory
password = mavenOssPassword //OSS user password: mandatory
close = '1' //Optional property. By default the staging repository is closed and artifacts are released to Maven Central. You can optionally turn this behaviour off (by puting 0 as value) and release the version manually.
}
}
}
}
publishing {
publications {
MyPublication(MavenPublication) {
from components.java
artifact sourcesJar
artifact testJar
artifact testSourcesJar
artifact javadocJar
groupId 'info.picocli'
artifactId bintrayPackage
version "$projectVersion"
pom.withXml {
def root = asNode()
root.appendNode('packaging', 'jar')
root.appendNode('name', bintrayPackage)
root.appendNode('description', description)
root.appendNode('url', 'http://picocli.info')
root.appendNode('inceptionYear', '2019')
root.children().last() + pomConfig
}
}
}
// copy module-info.class to META-INF/versions/9
multiRelease = true
}
19 changes: 19 additions & 0 deletions src/main/java9/module-info.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
/*
Copyright 2017 Remko Popma
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

module info.picocli {
exports picocli;
}

0 comments on commit d127560

Please sign in to comment.