/*
* Copyright ( c ) 2016 , 2022 , Oracle and / or its affiliates . All rights reserved .
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER .
*
* This code is free software ; you can redistribute it and / or modify it
* under the terms of the GNU General Public License version 2 only , as
* published by the Free Software Foundation .
*
* This code is distributed in the hope that it will be useful , but WITHOUT
* ANY WARRANTY ; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE . See the GNU General Public License
* version 2 for more details ( a copy is included in the LICENSE file that
* accompanied this code ) .
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work ; if not , write to the Free Software Foundation ,
* Inc . , 51 Franklin St , Fifth Floor , Boston , MA 02110 - 1301 USA .
*
* Please contact Oracle , 500 Oracle Parkway , Redwood Shores , CA 94065 USA
* or visit www . oracle . com if you need additional information or have any
* questions .
*/
/*
* @ test
* @ bug 8153654 8176333
* @ summary Tests for jdeps tool with multi - release jar files
* @ modules jdk . jdeps / com . sun . tools . jdeps
* @ library mrjar mrjar / base mrjar / 9 mrjar / 10 mrjar / v9 mrjar / v10
* @ build test . * p . * q . * foo /* Main
* @ run testng MultiReleaseJar
*/
import org.testng.Assert ;
import org.testng.annotations.AfterClass;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;
import java.io.File;
import java.io.InputStream;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.stream.Stream;
public class MultiReleaseJar {
Path mrjar;
String testJdk;
String fileSep;
Path cmdPath;
@BeforeClass
public void initialize() throws Exception {
String testClassPath = System.getProperty("test.class.path" , "" );
mrjar = Stream.of(testClassPath.split(File.pathSeparator))
.map(Paths::get)
.filter(e -> e.endsWith("mrjar" ))
.findAny()
.orElseThrow(() -> new InternalError("mrjar not found" ));
testJdk = System.getProperty("test.jdk" );
fileSep = System.getProperty("file.separator" );
cmdPath = Paths.get(testJdk, "bin" );
// build Version.jar, Version_9.jar and main.jar
Result r = run("jar -cf Version.jar -C base test --release 9 -C 9 test --release 10 -C 10 test" );
checkResult(r);
r = run("jar -cf Version_9.jar -C base test --release 9 -C 9 test" );
checkResult(r);
r = run("jar -cf Main.jar Main.class" );
checkResult(r);
r = run("jar -cf Foo.jar -C base p" );
checkResult(r);
Path foo = Paths.get(System.getProperty("test.classes" )).resolve("modules" ).resolve("foo" );
r = run("jar -uf Foo.jar --release 9 -C " + foo.toString() + " module-info.class --release 10 -C v10 q" );
checkResult(r);
}
@Test
public void basic() throws Exception {
Result r = run("jdeps -J-Duser.language=en -J-Duser.country=US --multi-release 9 -v missing.jar" );
checkResult(r, false , "Warning: Path does not exist: missing.jar" );
r = run("jdeps -J-Duser.language=en -J-Duser.country=US -v Version.jar" );
checkResult(r, false , "--multi-release option is not set" );
r = run("jdeps --multi-release base -v Version.jar" );
checkResult(r, true ,
"Version.jar ->" ,
"test.Version" ,
"test.Version"
);
r = run("jdeps --multi-release 9 -v Version.jar" );
checkResult(r, true ,
"Version.jar ->" ,
"9/test.NonPublic" ,
"9/test.NonPublic" ,
"9/test.Version" ,
"9/test.Version" ,
"9/test.Version" ,
"9/test.Version"
);
r = run("jdeps --multi-release 10 -v Version.jar" );
checkResult(r, true ,
"Version.jar ->" ,
"10/test.Version" ,
"10/test.Version" ,
"10/test.Version" ,
"10/test.Version" ,
"9/test.NonPublic" ,
"9/test.NonPublic"
);
r = run("jdeps -J-Duser.language=en -J-Duser.country=US --multi-release 8 -v Version.jar" );
checkResult(r, false , "Error: invalid argument for option: 8" );
r = run("jdeps -J-Duser.language=en -J-Duser.country=US --multi-release 9.1 -v Version.jar" );
checkResult(r, false , "Error: invalid argument for option: 9.1" );
runJdeps("Main.class" );
runJdeps("Main.jar" );
}
private void runJdeps(String path) throws Exception {
Result r = run("jdeps -J-Duser.language=en -J-Duser.country=US -v -R -cp Version.jar " + path);
checkResult(r, false , "--multi-release option is not set" );
r = run("jdeps -J-Duser.language=en -J-Duser.country=US -v -R -cp Version.jar --module-path Foo.jar -multi-release 9 " + path);
checkResult(r, false ,
"Error: unknown option: -multi-release" ,
"Usage: jdeps <options> <path" ,
"use --help"
);
r = run("jdeps -v -R -cp Version.jar --module-path Foo.jar --multi-release 9 " + path);
String name = path;
int index = path.lastIndexOf('/' );
if (index >= 0 ) {
name = path.substring(index + 1 , path.length());
}
checkResult(r, true ,
name + " -> Version.jar" ,
name + " -> foo" ,
name + " -> java.base" ,
"Main" ,
"Main" ,
"Main" ,
"Main" ,
"Version.jar -> java.base" ,
"9/test.NonPublic" ,
"9/test.NonPublic" ,
"9/test.Version" ,
"9/test.Version" ,
"9/test.Version" ,
"9/test.Version" ,
"foo" ,
"Foo.jar" ,
"requires mandated java.base" ,
"foo -> java.base" ,
"p.Foo"
);
r = run("jdeps -v -R -cp Version.jar --module-path Foo.jar --multi-release 10 " + path);
checkResult(r, true ,
name + " -> Version.jar" ,
name + " -> foo" ,
name + " -> java.base" ,
"Main" ,
"Main" ,
"Main" ,
"Main" ,
"Version.jar ->" ,
"10/test.Version" ,
"10/test.Version" ,
"10/test.Version" ,
"10/test.Version" ,
"9/test.NonPublic" ,
"9/test.NonPublic" ,
"foo" ,
"Foo.jar" ,
"requires mandated java.base" ,
"foo -> java.base" ,
"p.Foo"
);
r = run("jdeps -v -R -cp Version.jar --module-path Foo.jar --multi-release base " + path);
checkResult(r, true ,
name + " -> Version.jar" ,
name + " -> foo" ,
name + " -> java.base" ,
"Main" ,
"Main" ,
"Main" ,
"Main" ,
"Version.jar ->" ,
"test.Version" ,
"test.Version" ,
"foo" ,
"Foo.jar" ,
"requires mandated java.base" ,
"foo -> java.base" ,
"p.Foo"
);
r = run("jdeps -J-Duser.language=en -J-Duser.country=US -v -R -cp Version.jar --module-path Foo.jar --multi-release 9.1 " + path);
checkResult(r, false , "Error: invalid argument for option: 9.1" );
// Version_9.jar does not have any version 10 entry
r = run("jdeps -v -R -cp Version_9.jar --module-path Foo.jar --multi-release 10 " + path);
checkResult(r, true ,
name + " -> Version_9.jar" ,
name + " -> foo" ,
name + " -> java.base" ,
"Main" ,
"Main" ,
"Main" ,
"Main" ,
"Version_9.jar ->" ,
"9/test.NonPublic" ,
"9/test.NonPublic" ,
"9/test.Version" ,
"9/test.Version" ,
"9/test.Version" ,
"9/test.Version" ,
"foo" ,
"Foo.jar" ,
"requires mandated java.base" ,
"foo -> java.base" ,
"p.Foo"
);
}
@Test
public void ps_and_qs() throws Exception {
// build the jar file
Result r = run("jar -cf PQ.jar -C base p --release 9 -C v9 p -C v9 q --release 10 -C v10 q" );
checkResult(r);
r = run("jdeps -v -R -cp PQ.jar --multi-release base PQ.jar" );
checkResult(r, true ,
"PQ.jar -> java.base" ,
"p.Foo"
);
r = run("jdeps -v -R -cp PQ.jar --multi-release 9 PQ.jar" );
checkResult(r, true ,
"PQ.jar -> java.base" ,
"9/p.Foo" ,
"9/p.Foo" ,
"9/q.Bar"
);
r = run("jdeps -v -R -cp PQ.jar --multi-release 10 PQ.jar" );
checkResult(r, true ,
"PQ.jar -> java.base" ,
"10/q.Bar" ,
"10/q.Bar" ,
"10/q.Gee" ,
"9/p.Foo" ,
"9/p.Foo"
);
}
@Test
public void modularJar() throws Exception {
Result r = run("jdeps -v --multi-release 10 --module-path Foo.jar -m foo" );
checkResult(r, true ,
"foo" , // module name
"Foo.jar" , // the path to Foo.jar
"requires mandated java.base" , // module dependences
"foo -> java.base" ,
"10/q.Bar" ,
"10/q.Bar" ,
"10/q.Gee" ,
"p.Foo"
);
r = run("jdeps --multi-release 9 -cp Version.jar --module-path Foo.jar Main.jar" );
checkResult(r, true ,
"Main.jar -> Version.jar" ,
"Main.jar -> foo" ,
"Main.jar -> java.base" ,
"-> java.lang" ,
"-> p" ,
"-> test"
);
r = run("jdeps --multi-release 10 -cp Version.jar --module-path Foo.jar Main.jar" );
checkResult(r, true ,
"Main.jar -> Version.jar" ,
"Main.jar -> foo" ,
"Main.jar -> java.base" ,
"-> java.lang" ,
"-> p" ,
"-> test"
);
}
static class Result {
final String cmd;
final int rc;
final String out;
final String err;
Result(String cmd, int rc, String out, String err) {
this .cmd = cmd;
this .rc = rc;
this .out = out;
this .err = err;
}
}
Result run(String cmd) throws Exception {
String[] cmds = cmd.split(" +" );
cmds[0 ] = cmdPath.resolve(cmds[0 ]).toString();
ProcessBuilder pb = new ProcessBuilder(cmds);
pb.directory(mrjar.toFile());
Process p = null ;
try {
p = pb.start();
p.waitFor();
String out;
try (InputStream is = p.getInputStream()) {
out = new String(is.readAllBytes());
}
String err;
try (InputStream is = p.getErrorStream()) {
err = new String(is.readAllBytes());
}
return new Result(cmd, p.exitValue(), out, err);
} catch (Throwable t) {
if (p != null ) {
p.destroyForcibly().waitFor();
}
throw t;
}
}
void checkResult(Result r) throws Exception {
System.out.println(r.cmd);
System.out.println(r.out);
if (r.rc != 0 ) {
System.out.println(r.err);
throw new Exception("rc=" + r.rc);
}
System.out.println();
}
void checkResult(Result r, boolean checkrc, String... lines) throws Exception {
System.out.println(r.cmd);
System.out.println(r.out);
if (checkrc && r.rc != 0 ) {
System.out.println(r.err);
throw new Exception("rc=" + r.rc);
}
String[] out = r.out.split("\r?\n" );
Assert .assertEquals(out.length, lines.length);
int n = 0 ;
for (String line : lines) {
Assert .assertTrue(out[n++].contains(line), "\" " + line + " \"" );
}
System.out.println();
}
}
Messung V0.5 in Prozent C=91 H=92 G=91
¤ Dauer der Verarbeitung: 0.10 Sekunden
(vorverarbeitet am 2026-06-10)
¤
*© Formatika GbR, Deutschland