Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Extract referenced slf4j bundle for Maven runtime classpath again #961

Merged
merged 1 commit into from
Oct 1, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 15 additions & 14 deletions org.eclipse.m2e.core/src/org/eclipse/m2e/core/internal/Bundles.java
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ private Bundles() {

private static final Logger log = LoggerFactory.getLogger(Bundles.class);

public static List<String> getClasspathEntries(Bundle bundle) {
public static List<String> getClasspathEntries(Bundle bundle, boolean extractJar) {
log.debug("getClasspathEntries(Bundle={})", bundle);
Set<String> cp = new LinkedHashSet<>();
if(inDevelopmentMode()) {
Expand All @@ -53,13 +53,7 @@ public static List<String> getClasspathEntries(Bundle bundle) {
cp.addAll(parseBundleClasspath(bundle));
List<String> entries = new ArrayList<>();
for(String cpe : cp) {
String entry;
if(".".equals(cpe)) {
entry = FileLocator.getBundleFileLocation(bundle)
.orElseThrow(() -> new NoSuchElementException("Unable to locate bundle:" + bundle)).toString();
} else {
entry = getClasspathEntryPath(bundle, cpe);
}
String entry = getClasspathEntryPath(bundle, cpe, extractJar);
if(entry != null) {
log.debug("\tEntry:{}", entry);
entries.add(entry);
Expand All @@ -81,16 +75,23 @@ private static List<String> parseBundleClasspath(Bundle bundle) {
return List.of(".");
}

public static String getClasspathEntryPath(Bundle bundle, String cp) {
public static String getClasspathEntryPath(Bundle bundle, String cp, boolean extractJar) {
// try embedded entries first
URL url = bundle.getEntry(cp);
if(url != null) {
try {
try {
if(".".equals(cp)) {
if(!extractJar) {
return FileLocator.getBundleFileLocation(bundle)
.orElseThrow(() -> new NoSuchElementException("Unable to locate bundle:" + bundle)).getCanonicalPath();
}
cp = "/"; // get bundle's root entry below, which extracts the bundle's jar, if it not of shape 'dir' already
}
URL url = bundle.getEntry(cp);
if(url != null) {
String path = FileLocator.toFileURL(url).getFile();
return new Path(path).toOSString();
} catch(IOException ex) {
log.warn("Could not get entry {} for bundle {}", cp, bundle, ex);
}
} catch(IOException ex) {
log.warn("Could not get entry {} for bundle {}", cp, bundle, ex);
}

// in development mode entries can be absolute paths outside of bundle basedir
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,8 @@ public void createLauncherConfiguration(IMavenLauncherConfiguration collector, I
}
}

public static final Set<String> SLF4J_BUNDLE_NAMES = Set.of("org.slf4j.api", "slf4j.api");

private synchronized void initClasspath() {
if(CLASSPATH == null) {
Bundle mavenRuntimeBundle = findMavenEmbedderBundle();
Expand All @@ -120,9 +122,8 @@ private synchronized void initClasspath() {
addBundleClasspathEntries(allEntries, mavenRuntimeBundle, true);
allEntries.add(getEmbeddedSLF4JBinding(mavenRuntimeBundle));

Set<String> noDependencyBundles = Set.of("org.slf4j.api", "slf4j.api");
// Don't include dependencies of slf4j bundle to ensure no other than the slf4j-binding embedded into m2e.maven.runtime is available.
Set<Bundle> bundles = getRequiredBundles(mavenRuntimeBundle, noDependencyBundles);
Set<Bundle> bundles = getRequiredBundles(mavenRuntimeBundle, SLF4J_BUNDLE_NAMES);

for(Bundle bundle : bundles) {
addBundleClasspathEntries(allEntries, bundle, false);
Expand All @@ -141,11 +142,13 @@ private synchronized void initClasspath() {
}

private void addBundleClasspathEntries(Set<String> entries, Bundle bundle, boolean addFragments) {
entries.addAll(Bundles.getClasspathEntries(bundle));
boolean extractRoot = SLF4J_BUNDLE_NAMES.contains(bundle.getSymbolicName());
// Use extracted/directory form of slf4j bundles so that their jar-signing signature by the Maven-runtime classloader
entries.addAll(Bundles.getClasspathEntries(bundle, extractRoot));
Bundle[] fragments;
if(addFragments && (fragments = Platform.getFragments(bundle)) != null) {
for(Bundle fragment : fragments) {
entries.addAll(Bundles.getClasspathEntries(fragment));
entries.addAll(Bundles.getClasspathEntries(fragment, SLF4J_BUNDLE_NAMES.contains(fragment.getSymbolicName())));
}
}
}
Expand All @@ -154,7 +157,7 @@ private static String getEmbeddedSLF4JBinding(Bundle mavenBundle) {
String bindingPath = mavenBundle.getHeaders().get(M2E_SL4J_BINDING_HEADER);
Objects.requireNonNull(bindingPath,
() -> "Missing '" + M2E_SL4J_BINDING_HEADER + "' header in embedded Maven-runtime bundle");
String bindingJarPath = Bundles.getClasspathEntryPath(mavenBundle, bindingPath);
String bindingJarPath = Bundles.getClasspathEntryPath(mavenBundle, bindingPath, false);
return Objects.requireNonNull(bindingJarPath, () -> M2E_SL4J_BINDING_HEADER + " '" + bindingPath + "' not found");
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ public static AbstractMavenRuntime getMavenRuntime(ILaunchConfiguration configur
public static List<String> getCliResolver(AbstractMavenRuntime runtime) {
if(runtime.getVersion().startsWith("3.")) { //$NON-NLS-1$
Bundle m2eWorkspaceCLIBundle = FrameworkUtil.getBundle(WorkspaceState.class);
return Bundles.getClasspathEntries(m2eWorkspaceCLIBundle);
return Bundles.getClasspathEntries(m2eWorkspaceCLIBundle, false);
}
return Collections.emptyList(); // unsupported version of maven
}
Expand Down