Skip to content
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
5 changes: 3 additions & 2 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
# Extra Java Module Info Gradle Plugin - Changelog

## Version 1.14
* [Fixed] [#179](https://github.com/gradlex-org/extra-java-module-info/issues/179) - Combine 'preserveExisting' and 'exports'
* [Fixed] [#219](https://github.com/gradlex-org/extra-java-module-info/issues/219) - Combine 'preserveExisting' and 'removePackage'
* [New] [#207](https://github.com/gradlex-org/extra-java-module-info/issues/207) - Add 'exportAllPackagesExcept("org.exception", ...)' (Thanks [Tim Hurman](https://github.com/timhamoni) for contributing)
* [Fixed] [#179](https://github.com/gradlex-org/extra-java-module-info/issues/179) - Combine 'preserveExisting' and 'exports' (Thanks to [JabRef](https://github.com/JabRef/jabref) for providing a use case)
* [Fixed] [#219](https://github.com/gradlex-org/extra-java-module-info/issues/219) - Combine 'preserveExisting' and 'removePackage' (Thanks to [stewue](https://github.com/stewue) for providing a use case)
* [Fixed] [#223](https://github.com/gradlex-org/extra-java-module-info/issues/223) - Combine 'preserveExisting' and 'ignoreServiceProvider'
* [Fixed] [#227](https://github.com/gradlex-org/extra-java-module-info/issues/227) - Stable order for the mergeJar path input

Expand Down
4 changes: 3 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -73,11 +73,13 @@ extraJavaModuleInfo {
// skipLocalJars = true
module("commons-beanutils:commons-beanutils", "org.apache.commons.beanutils") {
exports("org.apache.commons.beanutils")
// or granuarly allowing access to a package by specific modules
// or granularly allowing access to a package by specific modules
// exports("org.apache.commons.beanutils",
// "org.mycompany.server", "org.mycompany.client")
// or simply export all packages
// exportAllPackages()
// or export all packages except specific named ones
// exportAllPackagesExcept("org.mycompany.notgood1", "org.mycompany.notgood2")

requiresTransitive("org.apache.commons.logging")
requires("java.sql")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -337,12 +337,17 @@ private void addModuleDescriptor(File originalJar, File moduleJar, ModuleInfo mo
providers,
packages);
mergeJars(moduleInfo, outputStream, providers, packages);
if (moduleInfo.exportAllPackages) {
moduleInfo.exportAllPackagesExceptions.forEach(it -> packages.remove(packageToPath(it)));
} else {
packages.clear();
}
outputStream.putNextEntry(newReproducibleEntry("module-info.class"));
outputStream.write(addModuleInfo(
moduleInfo,
providers,
versionFromFilePath(originalJar.toPath()),
moduleInfo.exportAllPackages ? packages : emptySet(),
packages,
moduleInfo.getRemovedPackages(),
moduleInfo.ignoreServiceProviders,
existingModuleInfo));
Expand Down
23 changes: 21 additions & 2 deletions src/main/java/org/gradlex/javamodule/moduleinfo/ModuleInfo.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,19 @@
package org.gradlex.javamodule.moduleinfo;

import java.util.Arrays;
import java.util.Collections;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.gradle.api.model.ObjectFactory;
import org.jspecify.annotations.NullMarked;
import org.jspecify.annotations.Nullable;

/**
* Data class to hold the information that should be added as module-info.class to an existing Jar file.
*/
@NullMarked
@SuppressWarnings("unused")
public class ModuleInfo extends ModuleSpec {

@Nullable
Expand All @@ -28,6 +29,7 @@ public class ModuleInfo extends ModuleSpec {
final Set<String> requiresStaticTransitive = new LinkedHashSet<>();
final Map<String, Set<String>> ignoreServiceProviders = new LinkedHashMap<>();
final Set<String> uses = new LinkedHashSet<>();
final Set<String> exportAllPackagesExceptions = new LinkedHashSet<>();

boolean exportAllPackages;
boolean requireAllDefinedDependencies;
Expand Down Expand Up @@ -120,7 +122,24 @@ public String getModuleVersion() {
* Automatically export all packages of the Jar. Can be used instead of individual 'exports()' statements.
*/
public void exportAllPackages() {
exportAllPackagesExcept(Collections.emptyList());
}

/**
* Automatically export all packages of the Jar. Can be used instead of individual 'exports()' statements.
* @param exceptions A list of packages not to export
*/
public void exportAllPackagesExcept(String... exceptions) {
exportAllPackagesExcept(Arrays.asList(exceptions));
}

/**
* Automatically export all packages of the Jar. Can be used instead of individual 'exports()' statements.
* @param exceptions A list of packages not to export
*/
public void exportAllPackagesExcept(List<String> exceptions) {
this.exportAllPackages = true;
exportAllPackagesExceptions.addAll(exceptions);
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -177,6 +177,53 @@ class EdgeCasesFunctionalTest extends Specification {
run().task(':run').outcome == TaskOutcome.SUCCESS
}

def "can automatically export all packages except specified of a legacy Jar"() {
given:
file("src/main/java/org/gradle/sample/app/Main.java") << """
package org.gradle.sample.app;

import javax.json.JsonString;
import javax.json.JsonValue;

public class Main {
public static void main(String[] args) {
JsonString jsonString = new JsonString() {
public boolean equals(Object obj) { return false; }
public CharSequence getChars() { return null; }
public String getString() { return null; }
public int hashCode() { return 0; }
public JsonValue.ValueType getValueType() { return null; }
};
}
}
"""

file("src/main/java/module-info.java") << """
module org.gradle.sample.app {
exports org.gradle.sample.app;

requires java.json;
}
"""
buildFile << """
dependencies {
implementation("org.glassfish:jakarta.json:1.1.6")
implementation("jakarta.json:jakarta.json-api:1.1.6")
}

extraJavaModuleInfo {
module("org.glassfish:jakarta.json", "java.json") {
// exportAllPackages()
exportAllPackagesExcept("javax.json", "javax.json.spi", "javax.json.stream")
}
}
"""

expect:
def result = failRun()
result.output.contains("error: package javax.json is not visible")
}

def "deriveAutomaticModuleNamesFromFileNames produces a build time error for invalid module names"() {
given:
buildFile << """
Expand Down
Loading