Skip to content

Commit

Permalink
feat: honor add-opens/exports from jar manifest (#1899)
Browse files Browse the repository at this point in the history
  • Loading branch information
maxandersen authored Jan 16, 2025
1 parent f603f8b commit 723bdc3
Show file tree
Hide file tree
Showing 4 changed files with 102 additions and 16 deletions.
1 change: 1 addition & 0 deletions src/main/java/dev/jbang/source/CmdGeneratorBuilder.java
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,7 @@ public CmdGenerator build() {
Alias alias = ((AliasResourceResolver.AliasedResourceRef) project.getResourceRef()).getAlias();
updateFromAlias(alias);
}

CmdGenerator gen;
if (project.isJShell() || interactive == Boolean.TRUE) {
gen = createJshCmdGenerator();
Expand Down
49 changes: 46 additions & 3 deletions src/main/java/dev/jbang/source/ProjectBuilder.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,15 @@
import java.io.InputStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.*;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.Properties;
import java.util.Set;
import java.util.function.Function;
import java.util.jar.Attributes;
import java.util.jar.JarEntry;
Expand All @@ -23,9 +31,22 @@
import dev.jbang.catalog.Catalog;
import dev.jbang.cli.BaseCommand;
import dev.jbang.cli.ExitException;
import dev.jbang.dependencies.*;
import dev.jbang.dependencies.DependencyResolver;
import dev.jbang.dependencies.DependencyUtil;
import dev.jbang.dependencies.Detector;
import dev.jbang.dependencies.MavenCoordinate;
import dev.jbang.dependencies.MavenRepo;
import dev.jbang.dependencies.ModularClassPath;
import dev.jbang.source.buildsteps.JarBuildStep;
import dev.jbang.source.resolvers.*;
import dev.jbang.source.resolvers.AliasResourceResolver;
import dev.jbang.source.resolvers.ClasspathResourceResolver;
import dev.jbang.source.resolvers.CombinedResourceResolver;
import dev.jbang.source.resolvers.FileResourceResolver;
import dev.jbang.source.resolvers.GavResourceResolver;
import dev.jbang.source.resolvers.LiteralScriptResourceResolver;
import dev.jbang.source.resolvers.RemoteResourceResolver;
import dev.jbang.source.resolvers.RenamingScriptResourceResolver;
import dev.jbang.source.resolvers.SiblingResourceResolver;
import dev.jbang.source.sources.JavaSource;
import dev.jbang.util.JavaUtil;
import dev.jbang.util.ModuleUtil;
Expand Down Expand Up @@ -359,6 +380,13 @@ public Project build(Source src) {
return updateProject(updateProjectMain(src, prj, getResourceResolver()));
}

/**
* Imports settings from jar MANIFEST.MF, pom.xml and more
*
* @param prj
* @param importModuleName
* @return
*/
private Project importJarMetadata(Project prj, boolean importModuleName) {
Path jar = prj.getResourceRef().getFile();
if (jar != null && Files.exists(jar)) {
Expand All @@ -381,6 +409,21 @@ private Project importJarMetadata(Project prj, boolean importModuleName) {
// buildJdk = JavaUtil.parseJavaVersion(ver);
prj.setJavaVersion(JavaUtil.parseJavaVersion(ver) + "+");
}

// we pass exports/opens into the project...
// TODO: this does mean we can't separate from user specified options and jar
// origined ones
// but not sure if needed?
// https://openjdk.org/jeps/261#Breaking-encapsulation
String exports = attrs.getValue("Add-Exports");
if (exports != null) {
prj.getManifestAttributes().put("Add-Exports", exports);
}
String opens = attrs.getValue("Add-Opens");
if (opens != null) {
prj.getManifestAttributes().put("Add-Opens", exports);
}

}

Optional<JarEntry> pom = jf.stream().filter(e -> e.getName().endsWith("/pom.xml")).findFirst();
Expand Down
16 changes: 16 additions & 0 deletions src/main/java/dev/jbang/source/generators/JarCmdGenerator.java
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,22 @@ protected List<String> generateCommandLineList() throws IOException {
JdkProvider.Jdk jdk = JdkManager.getOrInstallJdk(requestedJavaVersion);
String javacmd = JavaUtil.resolveInJavaHome("java", requestedJavaVersion);

if (jdk.getMajorVersion() > 9) {
String opens = ctx.getProject().getManifestAttributes().get("Add-Opens");
if (opens != null) {
for (String val : opens.split(" ")) {
optionalArgs.add("--add-opens=" + val + "=ALL-UNNAMED");
}
}

String exports = ctx.getProject().getManifestAttributes().get("Add-Exports");
if (exports != null) {
for (String val : exports.split(" ")) {
optionalArgs.add("--add-exports=" + val + "=ALL-UNNAMED");
}
}
}

addPropertyFlags(project.getProperties(), "-D", optionalArgs);

if (debugString != null) {
Expand Down
52 changes: 39 additions & 13 deletions src/test/java/dev/jbang/cli/TestRun.java
Original file line number Diff line number Diff line change
Expand Up @@ -9,19 +9,7 @@
import static org.hamcrest.CoreMatchers.endsWith;
import static org.hamcrest.CoreMatchers.nullValue;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.containsString;
import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.hasItem;
import static org.hamcrest.Matchers.hasKey;
import static org.hamcrest.Matchers.hasSize;
import static org.hamcrest.Matchers.hasXPath;
import static org.hamcrest.Matchers.instanceOf;
import static org.hamcrest.Matchers.is;
import static org.hamcrest.Matchers.matchesPattern;
import static org.hamcrest.Matchers.matchesRegex;
import static org.hamcrest.Matchers.not;
import static org.hamcrest.Matchers.notNullValue;
import static org.hamcrest.Matchers.startsWith;
import static org.hamcrest.Matchers.*;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.junit.jupiter.api.Assertions.fail;
Expand Down Expand Up @@ -2615,4 +2603,42 @@ void testNativeOptsVerbose() {
String arg = examplesTestFolder.resolve("helloworld.java").toAbsolutePath().toString();
CommandLine.ParseResult pr = JBang.getCommandLine().parseArgs("build", "-n", "-N=--verbose", arg);
}

@Test
void testReadingAddExports() throws IOException {
String jar = "com.google.googlejavaformat:google-java-format:1.25.2";

CommandLine.ParseResult pr = JBang.getCommandLine().parseArgs("run", jar);
Run run = (Run) pr.subcommand().commandSpec().userObject();

ProjectBuilder pb = run.createProjectBuilderForRun();
Project code = pb.build(jar);

BuildContext ctx = BuildContext.forProject(code);

String cmd = CmdGenerator.builder(ctx).build().generate();

assertThat(cmd,
containsString(
"--add-exports=jdk.compiler/com.sun.tools.javac.api=ALL-UNNAMED"));
}

@Test
void testReadingNoAddExportsOnJava8() throws IOException {
String jar = "com.google.googlejavaformat:google-java-format:1.25.2";

CommandLine.ParseResult pr = JBang.getCommandLine().parseArgs("run", "--java=8", jar);
Run run = (Run) pr.subcommand().commandSpec().userObject();

ProjectBuilder pb = run.createProjectBuilderForRun();
Project code = pb.build(jar);

BuildContext ctx = BuildContext.forProject(code);

String cmd = CmdGenerator.builder(ctx).build().generate();

assertThat(cmd,
not(containsString(
"--add-exports=jdk.compiler/com.sun.tools.javac.api=ALL-UNNAMED")));
}
}

0 comments on commit 723bdc3

Please sign in to comment.