diff --git a/BuildShaSumFile.java b/BuildShaSumFile.java new file mode 100644 index 0000000..8d5390c --- /dev/null +++ b/BuildShaSumFile.java @@ -0,0 +1,144 @@ +import java.io.FileWriter; +import java.io.IOException; +import java.io.InputStream; +import java.io.PrintWriter; +import java.io.UncheckedIOException; +import java.lang.module.ModuleDescriptor; +import java.lang.module.ModuleFinder; +import java.lang.module.ModuleReference; +import java.nio.file.Files; +import java.nio.file.Path; +import java.security.MessageDigest; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HexFormat; +import java.util.List; +import java.util.Map; +import java.util.Scanner; +import java.util.Set; +import java.util.function.Function; +import java.util.spi.ToolProvider; +import java.util.stream.Collectors; + +public class BuildShaSumFile { + + // Mirrored from ResourcePoolEntry.Type: + private enum Type { + CLASS_OR_RESOURCE(0), + CONFIG(1), + HEADER_FILE(2), + LEGAL_NOTICE(3), + MAN_PAGE(4), + NATIVE_CMD(5), + NATIVE_LIB(6), + TOP(7); + + int intVal; + + Type(int val) { + this.intVal = val; + } + + Integer getOrdinal() { + return intVal; + } + } + + private static final String RESOURCE_FILE_FORMAT = "jdk/tools/jlink/internal/runtimelink/fs_%s_files"; + private static final Map TYPE_MAP = Arrays.stream(Type.values()) + .collect(Collectors.toMap(Type::getOrdinal, Function.identity())); + private static final Module JLINK_MODULE = ToolProvider.findFirst("jlink").orElseThrow().getClass().getModule(); + private static final Set BINARIES_LIBS = Set.of(Type.NATIVE_CMD, Type.NATIVE_LIB); + + private final String outPutFile; + + public BuildShaSumFile(String output) { + this.outPutFile = output; + } + + /* + * Use the fs__files resource part of jdk.jlink to + * figure out the files part of a module from the JDK image. + * + * Note that the file is of the following format: + * ||| + * + * Example: + * 5|0|428e61a697dc05f585333888f0d9baaef7dad088c279f052e189e401471d0c94e99711f567c5d1e5d2e08259c3b320b9d239cbb610f7c347b2eff4eec8ce712c|bin/jmod + */ + private List getModuleFiles(String module, Set includeTypes) { + List moduleFiles = new ArrayList<>(); + String resourceFile = String.format(RESOURCE_FILE_FORMAT, module); + try (InputStream in = JLINK_MODULE.getResourceAsStream(resourceFile); + Scanner scanner = new Scanner(in)) { + while (scanner.hasNextLine()) { + String[] tokens = scanner.nextLine().split("\\|", 4); + Integer typeInt = Integer.valueOf(tokens[0]); + Type type = TYPE_MAP.get(typeInt); + boolean isSymlink = Integer.valueOf(tokens[1]) == 1; + if (includeTypes.contains(type) && !isSymlink) { + moduleFiles.add(tokens[3]); + } + } + } catch (IOException e) { + throw new UncheckedIOException(e); + } + return moduleFiles; + } + + private String sha512Sum(String file) { + try { + MessageDigest digest = MessageDigest.getInstance("SHA-512"); + try (InputStream is = Files.newInputStream(Path.of(System.getProperty("java.home")).resolve(Path.of(file)))) { + byte[] buf = new byte[1024]; + int readBytes = -1; + while ((readBytes = is.read(buf)) != -1) { + digest.update(buf, 0, readBytes); + } + } + byte[] hashSum = digest.digest(); + return HexFormat.of().formatHex(hashSum); + } catch (Exception e) { + throw new RuntimeException("Failed to generate hash sum"); + } + } + + public void produceHashSumFile() { + // Sanity check JEP 493 enabled builds: + String resourceFile = String.format(RESOURCE_FILE_FORMAT, "java.base"); + try (InputStream in = JLINK_MODULE.getResourceAsStream(resourceFile)) { + if (in == null) { + System.out.println("Not a JEP 493 enabled build. Aborting!"); + return; + } + } catch (IOException e) { + throw new UncheckedIOException(e); + } + try (PrintWriter pw = new PrintWriter(new FileWriter(Path.of(outPutFile).toFile()))) { + ModuleFinder.ofSystem().findAll().stream() + .map(ModuleReference::descriptor) + .map(ModuleDescriptor::name).forEach(m -> { + List moduleFiles = getModuleFiles(m, BINARIES_LIBS); + for (String file: moduleFiles) { + String shaSum = sha512Sum(file); + pw.println(String.format("%s|%s|%s", m, file, shaSum)); + } + }); + + } catch (IOException e) { + throw new UncheckedIOException(e); + } + System.out.println("File " + outPutFile + " written. " + + "You can feed that now to 'jlink's --sha-overrides option."); + } + + public static void main(String[] args) { + if (args.length != 1) { + System.err.println("Usage: " + BuildShaSumFile.class.getSimpleName() + " "); + System.exit(1); + } + BuildShaSumFile b = new BuildShaSumFile(args[0]); + b.produceHashSumFile(); + } + +} diff --git a/java-latest-openjdk-portable.spec b/java-latest-openjdk-portable.spec index c3ae220..e52e8af 100644 --- a/java-latest-openjdk-portable.spec +++ b/java-latest-openjdk-portable.spec @@ -402,7 +402,7 @@ %global top_level_dir_name %{vcstag} %global top_level_dir_name_backup %{top_level_dir_name}-backup %global buildver 36 -%global rpmrelease 4 +%global rpmrelease 5 #%%global tagsuffix %%{nil} # Priority must be 8 digits in total; up to openjdk 1.8, we were using 18..... so when we moved to 11, we had to add another digit %if %is_system_jdk @@ -458,10 +458,12 @@ %define jdkportablenameimpl() %(echo %{uniquesuffix ""} | sed "s;%{version}-%{release};\\0.portable%{1}.jdk;g" | sed "s;openjdkportable;el;g") %define jdkportablesourcesnameimpl() %(echo %{uniquesuffix ""} | sed "s;%{version}-%{release};\\0.portable%{1}.sources;g" | sed "s;openjdkportable;el;g" | sed "s;.%{_arch};.noarch;g") %define staticlibsportablenameimpl() %(echo %{uniquesuffix ""} | sed "s;%{version}-%{release};\\0.portable%{1}.static-libs;g" | sed "s;openjdkportable;el;g") +%define jmodsportablenameimpl() %(echo %{uniquesuffix ""} | sed "s;%{version}-%{release};\\0.portable%{1}.jmods;g" | sed "s;openjdkportable;el;g") %define jreportablearchive() %{expand:%{jreportablenameimpl -- %%{1}}.tar.xz} %define jdkportablearchive() %{expand:%{jdkportablenameimpl -- %%{1}}.tar.xz} %define jdkportablesourcesarchive() %{expand:%{jdkportablesourcesnameimpl -- %%{1}}.tar.xz} %define staticlibsportablearchive() %{expand:%{staticlibsportablenameimpl -- %%{1}}.tar.xz} +%define jmodsportablearchive() %{expand:%{jmodsportablenameimpl -- %%{1}}.tar.xz} %define jreportablename() %{expand:%{jreportablenameimpl -- %%{1}}} %define jdkportablename() %{expand:%{jdkportablenameimpl -- %%{1}}} %define jdkportablesourcesname() %{expand:%{jdkportablesourcesnameimpl -- %%{1}}} @@ -479,6 +481,7 @@ %define jdkportablearchiveForFiles() %(echo %{jdkportablearchive -- ""}) %define jdkportablesourcesarchiveForFiles() %(echo %{jdkportablesourcesarchive -- ""}) %define staticlibsportablearchiveForFiles() %(echo %{staticlibsportablearchive -- ""}) +%define jmodsportablearchiveForFiles() %(echo %{jmodsportablearchive -- ""}) ################################################################# # fix for https://bugzilla.redhat.com/show_bug.cgi?id=1111349 @@ -642,6 +645,10 @@ Source16: CheckVendor.java # Ensure translations are available for new timezones Source18: TestTranslations.java +# Regenerate jmod-less jlink hashsums after the build do all evil things +# The stripped debuginfo may fail this operation, but that is currently broken anyway +Source19: BuildShaSumFile.java + ############################################ # # RPM/distribution specific patches @@ -1110,17 +1117,9 @@ function buildjdk() { else libc_link_opt="dynamic"; fi - # For internal debug symbols the binaries and libraries - # get stripped by RPM post-build. Therefore add custom - # jlink arg-file which gets built into the lib/modules - # file so that we have a chance to override the recorded - # hash sums. - if [ "x${debug_symbols}" = "xinternal" ] ; then - jlink_flags="--save-jlink-argfiles=${jlink_args_file}" - create_jlink_argfile ${jlink_args_file} - else - jlink_flags="" - fi + + jlink_flags="--save-jlink-argfiles=${jlink_args_file}" + create_jlink_argfile ${jlink_args_file} echo "Using output directory: ${outputdir}"; echo "Checking build JDK ${buildjdk} is operational..." @@ -1372,6 +1371,7 @@ function packagejdk() { jdkname=%{jdkportablename -- "$nameSuffix"} jdkarchive=${packagesdir}/%{jdkportablearchive -- "$nameSuffix"} + jmodsarchive=${packagesdir}/%{jmodsportablearchive -- "$nameSuffix"} jrename=%{jreportablename -- "$nameSuffix"} jrearchive=${packagesdir}/%{jreportablearchive -- "$nameSuffix"} staticname=%{staticlibsportablename -- "$nameSuffix"} @@ -1423,6 +1423,11 @@ function packagejdk() { genchecksum ${miscarchive} fi + tar -cJf ${jmodsarchive} --exclude='**.debuginfo' ${jdkname}/jmods + genchecksum ${jmodsarchive} + + rm -rv ${jdkname}/jmods + tar -cJf ${jdkarchive} --exclude='**.debuginfo' ${jdkname} genchecksum ${jdkarchive} @@ -1508,6 +1513,10 @@ for suffix in %{build_loop} ; do stripjdk ${builddir} installjdk ${builddir} ${installdir} fi + + pushd ${installdir}/images/jdk/ + ./bin/java --add-opens=jdk.jlink/jdk.tools.jlink.internal.runtimelink=ALL-UNNAMED %{SOURCE19} ./conf/runtimelink-sha-overrides.conf + popd packagejdk ${installdir} ${packagesdir} %{altjavaoutputdir} %if %{system_libs} @@ -1700,6 +1709,7 @@ for suffix in %{build_loop} ; do # These definitions should match those in installjdk jdkarchive=${packagesdir}/%{jdkportablearchive -- "$nameSuffix"} + jmodsarchive=${packagesdir}/%{jmodsportablearchive -- "$nameSuffix"} jrearchive=${packagesdir}/%{jreportablearchive -- "$nameSuffix"} staticarchive=${packagesdir}/%{staticlibsportablearchive -- "$nameSuffix"} debugarchive=${packagesdir}/%{jdkportablearchive -- "${nameSuffix}.debuginfo"} @@ -1707,6 +1717,8 @@ for suffix in %{build_loop} ; do mv ${jdkarchive} $RPM_BUILD_ROOT%{_jvmdir}/ mv ${jdkarchive}.sha256sum $RPM_BUILD_ROOT%{_jvmdir}/ + mv ${jmodsarchive} $RPM_BUILD_ROOT%{_jvmdir}/ + mv ${jmodsarchive}.sha256sum $RPM_BUILD_ROOT%{_jvmdir}/ mv ${jrearchive} $RPM_BUILD_ROOT%{_jvmdir}/ mv ${jrearchive}.sha256sum $RPM_BUILD_ROOT%{_jvmdir}/ @@ -1756,6 +1768,8 @@ done %{_jvmdir}/%{jdkportablearchive -- .debuginfo} %{_jvmdir}/%{jdkportablearchiveForFiles}.sha256sum %{_jvmdir}/%{jdkportablearchive -- .debuginfo}.sha256sum +%{_jvmdir}/%{jmodsportablearchiveForFiles} +%{_jvmdir}/%{jmodsportablearchiveForFiles}.sha256sum %endif %if %{include_normal_build} @@ -1778,6 +1792,8 @@ done %files devel-slowdebug %{_jvmdir}/%{jdkportablearchive -- .slowdebug} %{_jvmdir}/%{jdkportablearchive -- .slowdebug}.sha256sum +%{_jvmdir}/%{jmodsportablearchive -- .slowdebug} +%{_jvmdir}/%{jmodsportablearchive -- .slowdebug}.sha256sum %if %{include_staticlibs} %files static-libs-slowdebug @@ -1794,6 +1810,8 @@ done %files devel-fastdebug %{_jvmdir}/%{jdkportablearchive -- .fastdebug} %{_jvmdir}/%{jdkportablearchive -- .fastdebug}.sha256sum +%{_jvmdir}/%{jmodsportablearchive -- .fastdebug} +%{_jvmdir}/%{jmodsportablearchive -- .fastdebug}.sha256sum %if %{include_staticlibs} %files static-libs-fastdebug