Skip to content

Commit 30b7c08

Browse files
author
Maxim Butov
committed
Multi-release jar.
1 parent c30135b commit 30b7c08

File tree

17 files changed

+155
-49
lines changed

17 files changed

+155
-49
lines changed

.github/workflows/build.yml

+2-1
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ jobs:
2020
java-version: |
2121
8
2222
9
23+
15
2324
16
2425
17
2526
distribution: 'adopt'
@@ -31,6 +32,6 @@ jobs:
3132
with:
3233
gradle-version: wrapper
3334
arguments: |
34-
-Porg.gradle.java.installations.fromEnv=JAVA_HOME_8_X64,JAVA_HOME_9_X64,JAVA_HOME_16_X64,JAVA_HOME_17_X64
35+
-Porg.gradle.java.installations.fromEnv=JAVA_HOME_8_X64,JAVA_HOME_9_X64,JAVA_HOME_15_X64,JAVA_HOME_16_X64,JAVA_HOME_17_X64
3536
clean
3637
build

checkstyle/checkstyle.xml

+1-1
Original file line numberDiff line numberDiff line change
@@ -186,7 +186,7 @@
186186
</module>
187187

188188
<module name="TypeName">
189-
<property name="format" value="^[A-Z][a-zA-Z0-9]*$"/>
189+
<property name="format" value="^[A-Z\$][a-zA-Z0-9\$]*$"/>
190190
<property name="applyToPublic" value="true"/>
191191
<property name="applyToProtected" value="true"/>
192192
<property name="applyToPackage" value="true"/>

jdk15/build.gradle.kts

+23
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
plugins {
2+
id("java-conventions")
3+
id("optional-dependencies")
4+
id("checkstyle-conventions")
5+
id("build-utils")
6+
}
7+
8+
dependencies {
9+
10+
implementation(project(":jdk8"))
11+
implementation(project(":jdk9"))
12+
13+
testImplementation(testFixtures(project(":jdk8")))
14+
testImplementation("org.hamcrest:hamcrest:2.2")
15+
testImplementation("org.junit.jupiter:junit-jupiter:5.10.0")
16+
17+
}
18+
19+
java {
20+
toolchain {
21+
languageVersion.set(JavaLanguageVersion.of(15))
22+
}
23+
}

jdk9/src/main/java/io/github/sugarcubes/cloner/Jdk15ConfigurationImpl.java renamed to jdk15/src/main/java/io/github/sugarcubes/cloner/JdkConfigurationImpl$Jdk15.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@
2323
*
2424
* @author Maxim Butov
2525
*/
26-
class Jdk15ConfigurationImpl extends Jdk9ConfigurationImpl {
26+
class JdkConfigurationImpl$Jdk15 extends JdkConfigurationImpl$Jdk9 {
2727

2828
@Override
2929
public void initialize() {
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
/*
2+
* Copyright 2017-2023 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package io.github.sugarcubes.cloner;
17+
18+
/**
19+
* Actual JDK configuration.
20+
*/
21+
final class JdkConfigurationImpl extends JdkConfigurationImpl$Jdk15 {
22+
23+
}

jdk16/build.gradle.kts

+1
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ dependencies {
99

1010
implementation(project(":jdk8"))
1111
implementation(project(":jdk9"))
12+
implementation(project(":jdk15"))
1213

1314
testImplementation(testFixtures(project(":jdk8")))
1415
testImplementation("org.hamcrest:hamcrest:2.2")

jdk16/src/main/java/io/github/sugarcubes/cloner/Jdk16ConfigurationImpl.java renamed to jdk16/src/main/java/io/github/sugarcubes/cloner/JdkConfigurationImpl$Jdk16.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020
*
2121
* @author Maxim Butov
2222
*/
23-
class Jdk16ConfigurationImpl extends Jdk15ConfigurationImpl {
23+
class JdkConfigurationImpl$Jdk16 extends JdkConfigurationImpl$Jdk15 {
2424

2525
@Override
2626
@SuppressWarnings({"unchecked", "rawtypes"})
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
/*
2+
* Copyright 2017-2023 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package io.github.sugarcubes.cloner;
17+
18+
/**
19+
* Actual JDK configuration.
20+
*/
21+
final class JdkConfigurationImpl extends JdkConfigurationImpl$Jdk16 {
22+
23+
}

jdk8/src/main/java/io/github/sugarcubes/cloner/JdkConfiguration.java

+2-1
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,8 @@ interface JdkConfiguration {
2727
/**
2828
* Initializes configuration.
2929
*/
30-
void initialize();
30+
default void initialize() {
31+
}
3132

3233
/**
3334
* Returns immutable types.

jdk8/src/main/java/io/github/sugarcubes/cloner/JdkConfigurationHolder.java

+2-29
Original file line numberDiff line numberDiff line change
@@ -22,37 +22,10 @@
2222
*/
2323
class JdkConfigurationHolder {
2424

25-
static final JdkConfiguration CONFIGURATION;
25+
static final JdkConfiguration CONFIGURATION = new JdkConfigurationImpl();
2626

2727
static {
28-
JdkConfiguration configuration = null;
29-
30-
String packageName = JdkConfigurationHolder.class.getPackage().getName();
31-
for (int version = JdkVersion.CURRENT.version; version >= JdkVersion.MINIMAL.version; version--) {
32-
String configurationClassName = String.format("%s.Jdk%dConfigurationImpl", packageName, version);
33-
Class<JdkConfiguration> configurationClass;
34-
try {
35-
configurationClass = (Class<JdkConfiguration>) Class.forName(configurationClassName);
36-
}
37-
catch (ClassNotFoundException e) {
38-
continue;
39-
}
40-
try {
41-
configuration = configurationClass.getDeclaredConstructor().newInstance();
42-
}
43-
catch (Exception e) {
44-
throw new ClonerException("Cannot instantiate configuration.", e);
45-
}
46-
break;
47-
}
48-
49-
if (configuration == null) {
50-
throw Checks.mustNotHappen();
51-
}
52-
53-
CONFIGURATION = configuration;
54-
55-
configuration.initialize();
28+
CONFIGURATION.initialize();
5629
}
5730

5831
}

jdk8/src/main/java/io/github/sugarcubes/cloner/Jdk8ConfigurationImpl.java renamed to jdk8/src/main/java/io/github/sugarcubes/cloner/JdkConfigurationImpl$Jdk8.java

+2-3
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@
2727
*
2828
* @author Maxim Butov
2929
*/
30-
class Jdk8ConfigurationImpl implements JdkConfiguration {
30+
class JdkConfigurationImpl$Jdk8 implements JdkConfiguration {
3131

3232
/**
3333
* JDK immutable types.
@@ -77,8 +77,7 @@ class Jdk8ConfigurationImpl implements JdkConfiguration {
7777

7878
private UnsafeBridge unsafe;
7979

80-
@Override
81-
public void initialize() {
80+
public JdkConfigurationImpl$Jdk8() {
8281
systemWideSingletons.addAll(Arrays.asList(
8382
Collections.emptyEnumeration(),
8483
Collections.emptyIterator(),
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
/*
2+
* Copyright 2017-2023 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package io.github.sugarcubes.cloner;
17+
18+
/**
19+
* Actual JDK configuration.
20+
*/
21+
final class JdkConfigurationImpl extends JdkConfigurationImpl$Jdk8 {
22+
23+
}
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,5 @@
2020
*
2121
* @author Maxim Butov
2222
*/
23-
class _The_pencil_thought_it_was_the_sharpest_in_the {
24-
23+
class $$$ {
2524
}

jdk9/src/main/java/io/github/sugarcubes/cloner/Jdk9ConfigurationImpl.java renamed to jdk9/src/main/java/io/github/sugarcubes/cloner/JdkConfigurationImpl$Jdk9.java

+3-5
Original file line numberDiff line numberDiff line change
@@ -28,11 +28,9 @@
2828
*
2929
* @author Maxim Butov
3030
*/
31-
class Jdk9ConfigurationImpl extends Jdk8ConfigurationImpl {
31+
class JdkConfigurationImpl$Jdk9 extends JdkConfigurationImpl$Jdk8 {
3232

33-
@Override
34-
public void initialize() {
35-
super.initialize();
33+
public JdkConfigurationImpl$Jdk9() {
3634
systemWideSingletons.addAll(Arrays.asList(List.of(), Set.of(), Map.of()));
3735
}
3836

@@ -48,7 +46,7 @@ protected UnsafeBridge getUnsafeImpl() {
4846
}
4947

5048
private final Instrumentation instrumentation = ClonerAgent.getInstrumentation();
51-
private final Module clonerModule = Jdk9ConfigurationImpl.class.getModule();
49+
private final Module clonerModule = JdkConfigurationImpl$Jdk9.class.getModule();
5250
private final Set<Class<?>> accessible = Collections.newSetFromMap(new WeakHashMap<>());
5351

5452
@Override
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
/*
2+
* Copyright 2017-2023 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package io.github.sugarcubes.cloner;
17+
18+
/**
19+
* Actual JDK configuration.
20+
*/
21+
final class JdkConfigurationImpl extends JdkConfigurationImpl$Jdk9 {
22+
23+
}

settings.gradle.kts

+1
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ rootProject.name = "sugar-cubes-cloner"
33
include("jdk8")
44
include("jdk9")
55
include("jdk9-module")
6+
include("jdk15")
67
include("jdk16")
78
include("sugar-cubes-cloner")
89

sugar-cubes-cloner/build.gradle.kts

+23-5
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ val clonerModules = listOf(
1111
project(":jdk8"),
1212
project(":jdk9"),
1313
project(":jdk9-module"),
14+
project(":jdk15"),
1415
project(":jdk16"),
1516
)
1617

@@ -34,14 +35,14 @@ jarTasks.forEach {
3435
mapOf(
3536
"Implementation-Title" to project.name,
3637
"Implementation-Version" to project.version,
38+
"Multi-Release" to true,
3739
"Automatic-Module-Name" to "io.github.sugarcubes.cloner",
3840
"Created-By" to
3941
System.getProperty("java.version") + " " + System.getProperty("java.specification.vendor"),
4042
)
4143
)
4244

4345
clonerModules.forEach {
44-
from(it.sourceSets.main.get().output)
4546
manifest {
4647
attributes(it.tasks.jar.get().manifest.attributes)
4748
}
@@ -52,9 +53,26 @@ jarTasks.forEach {
5253

5354
tasks.named<Jar>("jar") {
5455

56+
from(project(":jdk8").sourceSets.main.get().output)
57+
58+
into("META-INF/versions/9") {
59+
from(project(":jdk9").sourceSets.main.get().output)
60+
from(project(":jdk9-module").sourceSets.main.get().output) {
61+
// exclude placeholder
62+
exclude("**/$$$.*")
63+
}
64+
}
65+
66+
into("META-INF/versions/15") {
67+
from(project(":jdk15").sourceSets.main.get().output)
68+
}
69+
70+
into("META-INF/versions/16") {
71+
from(project(":jdk16").sourceSets.main.get().output)
72+
}
73+
5574
clonerModules.forEach {
5675
dependsOn(it.tasks.named<Jar>("jar"))
57-
from(it.sourceSets.main.get().output)
5876
manifest {
5977
attributes(it.tasks.jar.get().manifest.attributes)
6078
}
@@ -87,7 +105,7 @@ tasks.withType<Javadoc> {
87105
// opts.addBooleanOption("J--add-exports=java.base/jdk.internal.misc=io.github.sugarcubes.cloner", true)
88106

89107
// exclude placeholder
90-
exclude("**/_*.*")
108+
exclude("**/$$$.*")
91109

92110
exclude("**/JdkInternalMiscUnsafeBridge.*")
93111
}
@@ -97,10 +115,10 @@ tasks.named<Jar>("sourcesJar") {
97115
from(it.sourceSets.main.get().allSource)
98116
}
99117

100-
exclude("**/*.class")
118+
duplicatesStrategy = DuplicatesStrategy.INCLUDE
101119

102120
// exclude placeholder
103-
exclude("**/_*.*")
121+
exclude("**/$$$.*")
104122
}
105123

106124
publishing {

0 commit comments

Comments
 (0)