Something went wrong. Try again.
Backend environment for match hosting for lance.blue
Something went wrong. Try again.
Python
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143#!/usr/bin/env python3"""Report which JDK modules the shipped jars reference but JRE_MODULES omits.
python3 tests/module-scan.py <jdk-dir> <jar-or-dir> [<jar-or-dir> ...]
python3 tests/module-scan.py /opt/jdk /opt/suramadu /opt/megamek
Why this exists: the jlink runtime keeps ~18 of the JDK's modules, and a missingone does not fail the build. It fails at runtime, often far from the cause -leaving out jdk.net let Suramadu bind its port and then throwNoClassDefFoundError on every accept(), which looks like a network problemrather than a missing module.
Run it after bumping MegaMek or Suramadu, or when adding a dependency.
Read the output as a starting point, not a shopping list. A static reference isnot proof of runtime need: bundled libraries routinely reference javax.tools orjava.rmi on code paths nothing takes. Adding all of them here would cost 14MBfor four modules that have never been needed. Add one when something failswithout it, and record why in versions.env.
Not part of ./test.sh - it needs the extracted third-party trees, and itreports rather than passes or fails."""
import globimport osimport reimport subprocessimport sysimport zipfile
# Kept in step with versions.env by hand. A mismatch shows up as noise in the# output rather than a wrong answer.CURRENT = { "java.base", "java.datatransfer", "java.xml", "java.prefs", "java.desktop", "java.logging", "java.management", "java.security.sasl", "java.naming", "java.scripting", "java.transaction.xa", "java.sql", "jdk.unsupported", "jdk.crypto.ec", "jdk.zipfs", "java.instrument", "jdk.net", "jdk.accessibility", "jdk.management",}
# A capturing group here would make findall return just the group, so every# match collapses to "jdk" and the scan silently finds nothing.REF = re.compile(rb"(?:java|javax|jdk|sun|com/sun)/[a-zA-Z0-9_/$]+")
def package_map(jdk): """package -> module, for every observable module in this JDK.""" mods = [ m.split("@")[0] for m in subprocess.run( [f"{jdk}/bin/java", "--list-modules"], capture_output=True, text=True, check=True, ).stdout.split() ] pkgs = {} for m in mods: out = subprocess.run( [f"{jdk}/bin/java", "--describe-module", m], capture_output=True, text=True ).stdout for line in out.splitlines(): line = line.strip() if line.startswith(("exports ", "contains ")): pkgs.setdefault(line.split()[1], m) return pkgs
def jars_under(path): if os.path.isfile(path) and path.endswith(".jar"): return [path] return sorted(glob.glob(os.path.join(path, "**", "*.jar"), recursive=True))
def modules_referenced(jars, pkg2mod): found = set() for j in jars: try: z = zipfile.ZipFile(j) except Exception: continue for name in z.namelist(): if not name.endswith(".class"): continue try: data = z.read(name) except Exception: continue for ref in REF.findall(data): parts = ref.decode().split("/") # Longest matching package wins: java.nio.file before java.nio. for cut in range(len(parts) - 1, 1, -1): cand = ".".join(parts[:cut]) if cand in pkg2mod: found.add(pkg2mod[cand]) break return found
def main(): if len(sys.argv) < 3: sys.exit(__doc__) jdk, targets = sys.argv[1], sys.argv[2:] pkg2mod = package_map(jdk)
everything = set() for t in targets: jars = jars_under(t) mods = modules_referenced(jars, pkg2mod) missing = sorted(mods - CURRENT) print(f"\n{t} ({len(jars)} jars)") print(" referenced but not in JRE_MODULES:") for m in missing: print(f" {m}") if not missing: print(" (none)") everything |= set(missing)
print("\nunion:", ",".join(sorted(everything)) or "(nothing missing)") print("\nMeasure before adding any of these:") print(f" {jdk}/bin/jlink --add-modules <list> --strip-debug \\") print(" --no-man-pages --no-header-files --compress=zip-6 --output /tmp/jre")
if __name__ == "__main__": main()