From e88f175a7a95d4c3f5ac354bcb068bc9245b9bbe Mon Sep 17 00:00:00 2001 From: Hannes Wellmann Date: Fri, 12 Aug 2022 00:30:12 +0200 Subject: [PATCH] backport: Use the actual system-packages from the JVM for Product/Site export Fixes https://github.com/eclipse-pde/eclipse.pde/issues/194 for PDE-build Refs: https://github.com/eclipse-pde/eclipse.pde/issues/624 --- org.eclipse.pde.build/META-INF/MANIFEST.MF | 2 + .../pde/internal/build/site/PDEState.java | 100 ++++++++++-------- 2 files changed, 56 insertions(+), 46 deletions(-) diff --git a/org.eclipse.pde.build/META-INF/MANIFEST.MF b/org.eclipse.pde.build/META-INF/MANIFEST.MF index bcc6657068..2360006943 100644 --- a/org.eclipse.pde.build/META-INF/MANIFEST.MF +++ b/org.eclipse.pde.build/META-INF/MANIFEST.MF @@ -26,6 +26,8 @@ Require-Bundle: org.eclipse.core.runtime;bundle-version="[3.2.0,4.0.0)", org.eclipse.equinox.p2.repository.tools;bundle-version="[2.0.0,3.0.0)";resolution:=optional, org.eclipse.equinox.p2.director.app;bundle-version="1.0.200", org.eclipse.equinox.p2.publisher.eclipse;bundle-version="1.0.0" + org.eclipse.jdt.core;bundle-version="[3.28.0,4.0.0)", + org.eclipse.jdt.launching;bundle-version="[3.19.700,4.0.0)" Import-Package: org.eclipse.equinox.frameworkadmin;version="[2.0.0,3.0.0)", org.eclipse.equinox.internal.p2.core.helpers, org.eclipse.equinox.internal.p2.engine, diff --git a/org.eclipse.pde.build/src/org/eclipse/pde/internal/build/site/PDEState.java b/org.eclipse.pde.build/src/org/eclipse/pde/internal/build/site/PDEState.java index 770bfe7521..6912a54bec 100644 --- a/org.eclipse.pde.build/src/org/eclipse/pde/internal/build/site/PDEState.java +++ b/org.eclipse.pde.build/src/org/eclipse/pde/internal/build/site/PDEState.java @@ -14,13 +14,15 @@ package org.eclipse.pde.internal.build.site; import java.io.*; -import java.net.URL; -import java.net.URLConnection; import java.util.*; import java.util.jar.JarFile; import java.util.zip.ZipEntry; import java.util.zip.ZipFile; import org.eclipse.core.runtime.*; +import org.eclipse.jdt.core.JavaCore; +import org.eclipse.jdt.launching.IVMInstall; +import org.eclipse.jdt.launching.JavaRuntime; +import org.eclipse.jdt.launching.environments.IExecutionEnvironment; import org.eclipse.osgi.service.resolver.*; import org.eclipse.osgi.service.resolver.VersionRange; import org.eclipse.osgi.util.ManifestElement; @@ -31,7 +33,7 @@ // This class provides a higher level API on the state public class PDEState implements IPDEBuildConstants, IBuildPropertiesConstants { private static final String[] MANIFEST_ENTRIES = {Constants.BUNDLE_LOCALIZATION, Constants.BUNDLE_NAME, Constants.BUNDLE_VENDOR, ECLIPSE_BUNDLE_SHAPE, ECLIPSE_SOURCE_BUNDLE, ECLIPSE_SOURCE_REF}; - private static int LAST_SUPPORTED_JDK = 17; + private static final int LAST_SUPPORTED_JDK = Integer.parseInt(JavaCore.latestSupportedJavaVersion()); private StateObjectFactory factory; protected State state; private long id; @@ -437,10 +439,8 @@ public void resolveState() { String previousEE = eeJava9; for (String execEnvID : eeJava10AndBeyond) { prop = new Hashtable<>(); - Properties javaProfilePropertiesForVMPackage = getJavaProfilePropertiesForVMPackage(execEnvID); - if (javaProfilePropertiesForVMPackage != null) { - systemPackages = javaProfilePropertiesForVMPackage.getProperty(Constants.FRAMEWORK_SYSTEMPACKAGES); - } + IExecutionEnvironment env = JavaRuntime.getExecutionEnvironmentsManager().getEnvironment(execEnvID); + systemPackages = querySystemPackages(env); String currentEE = previousEE + "," + execEnvID; //$NON-NLS-1$ if (systemPackages == null) { previousEE = currentEE; @@ -461,6 +461,53 @@ public void resolveState() { } } + public static String querySystemPackages(IExecutionEnvironment environment) { + // Copy of org.eclipse.pde.internal.core.TargetPlatformHelper.querySystemPackages() + IVMInstall vm = bestVmInstallFor(environment); + if (vm == null || !JavaRuntime.isModularJava(vm)) { + return null; + } + String release = environment.getProfileProperties().getProperty(JavaCore.COMPILER_COMPLIANCE); + try { + Collection packages = new TreeSet<>(); + String jrtPath = "lib/" + org.eclipse.jdt.internal.compiler.util.JRTUtil.JRT_FS_JAR; //$NON-NLS-1$ + String path = new File(vm.getInstallLocation(), jrtPath).toString(); // $NON-NLS-1$ + var jrt = org.eclipse.jdt.internal.core.builder.ClasspathLocation.forJrtSystem(path, null, null, release); + for (String moduleName : jrt.getModuleNames(null)) { + var module = jrt.getModule(moduleName); + if (module == null) { + continue; + } + for (var packageExport : module.exports()) { + if (!packageExport.isQualified()) { + packages.add(new String(packageExport.name())); + } + } + } + return String.join(",", packages); //$NON-NLS-1$ + } catch (CoreException e) { + Platform.getLog(PDEState.class).log(Status.error("failed to read system packages for " + environment, e)); //$NON-NLS-1$ + } + return null; + } + + private static IVMInstall bestVmInstallFor(IExecutionEnvironment environment) { + IVMInstall defaultVM = environment.getDefaultVM(); + if (defaultVM != null) { + return defaultVM; + } + IVMInstall[] compatible = environment.getCompatibleVMs(); + if (compatible.length == 0) { + return null; + } + for (IVMInstall vm : compatible) { + if (environment.isStrictlyCompatible(vm)) { + return vm; + } + } + return compatible[0]; + } + public State getState() { return state; } @@ -734,43 +781,4 @@ public ProfileManager getProfileManager() { } return profileManager; } - - private static Properties getJavaProfilePropertiesForVMPackage(String ee) { - Bundle apitoolsBundle = Platform.getBundle("org.eclipse.pde.api.tools"); //$NON-NLS-1$ - if (apitoolsBundle == null) { - return null; - } - URL systemPackageProfile = apitoolsBundle.getEntry("system_packages" + '/' + ee.replace('/', '_') + "-systempackages.profile"); //$NON-NLS-1$ //$NON-NLS-2$ - if (systemPackageProfile != null) { - return getPropertiesFromURL(systemPackageProfile); - - } - return null; - } - - private static Properties getPropertiesFromURL(URL profileURL) { - InputStream is = null; - try { - profileURL = FileLocator.resolve(profileURL); - URLConnection openConnection = profileURL.openConnection(); - openConnection.setUseCaches(false); - is = openConnection.getInputStream(); - if (is != null) { - Properties profile = new Properties(); - profile.load(is); - return profile; - } - } catch (IOException e) { - // nothing to do - } finally { - try { - if (is != null) { - is.close(); - } - } catch (IOException e) { - // nothing to do - } - } - return null; - } }