Skip to content

Commit

Permalink
Merge pull request #1048 from iajn/NETBEANS-1774
Browse files Browse the repository at this point in the history
NETBEANS-1774 Use fragment host instead of fragment bundle for class loading in Netigso
  • Loading branch information
Jaroslav Tulach committed Feb 28, 2019
2 parents ec8a320 + ef82f30 commit 5f7d848
Show file tree
Hide file tree
Showing 3 changed files with 112 additions and 4 deletions.
16 changes: 13 additions & 3 deletions platform/core.netigso/src/org/netbeans/core/netigso/Netigso.java
Original file line number Diff line number Diff line change
Expand Up @@ -267,7 +267,7 @@ protected Set<String> createLoader(ModuleInfo m, ProxyClassLoader pcl, File jar)
}
throw new IOException("Not found bundle:" + m.getCodeNameBase());
}
ClassLoader l = new NetigsoLoader(b, m, jar);
NetigsoLoader l = new NetigsoLoader(b, m, jar);
Set<String> pkgs = new HashSet<String>();
String[] knownPkgs = registered.get(m.getCodeNameBase());
Object exported = b.getHeaders("").get("Export-Package");
Expand Down Expand Up @@ -326,7 +326,17 @@ protected Set<String> createLoader(ModuleInfo m, ProxyClassLoader pcl, File jar)
if (isRealBundle(b)) {
throw possible;
}
LOG.log(Level.FINE, "Not starting fragment {0}", m.getCodeNameBase());
// Bundle is a fragment, replace it with host in classloader
String fragmentHost = b.getHeaders("").get("Fragment-Host");
Bundle hostBundle = findBundle(fragmentHost);
if (hostBundle == null) {
LOG.log(Level.WARNING, "Failed to locate fragment host bundle {0} for fragment bundle {1}",
new Object[]{fragmentHost, m.getCodeNameBase()});
throw new IOException("Not found bundle: " + hostBundle);
}
l.setBundle(hostBundle);
LOG.log(Level.FINE, "Not starting fragment {0}, using host bundle {1} for classloading instead",
new Object[]{m.getCodeNameBase(), fragmentHost});
}
return pkgs;
} catch (BundleException ex) {
Expand All @@ -349,7 +359,7 @@ private static boolean isRealBundle(Bundle b) {
@Override
protected void stopLoader(ModuleInfo m, ClassLoader loader) {
NetigsoLoader nl = (NetigsoLoader)loader;
Bundle b = nl.bundle;
Bundle b = nl.getBundle();
try {
assert b != null;
try {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,13 +33,21 @@

final class NetigsoLoader extends ProxyClassLoader {
private static final Logger LOG = Logger.getLogger(NetigsoLoader.class.getName());
final Bundle bundle;
private Bundle bundle;

NetigsoLoader(Bundle b, ModuleInfo m, File jar) {
super(new ClassLoader[0], true);
this.bundle = b;
}

public Bundle getBundle() {
return bundle;
}

public void setBundle(Bundle bundle) {
this.bundle = bundle;
}

@Override
public URL findResource(String name) {
//Netigso.start();
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.netbeans.core.netigso;

import java.io.File;
import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;
import org.netbeans.MockEvents;
import org.netbeans.MockModuleInstaller;
import org.netbeans.Module;
import org.netbeans.ModuleManager;

public class NetigsoLoaderOSGiFragmentTest extends NetigsoHid {

private static final String HOST_MANIFEST = ""
+ "Bundle-SymbolicName: org.foo\n"
+ "Bundle-Version: 1.1.0\n"
+ "Bundle-ManifestVersion: 2\n"
+ "\n\n";

private static final String FRAGMENT_MANIFEST = ""
+ "Fragment-Host: org.foo\n"
+ "Bundle-SymbolicName: org.bar\n"
+ "Bundle-Version: 1.1.0\n"
+ "Bundle-ManifestVersion: 2\n"
+ "Export-Package: org.bar\n"
+ "\n\n";

public NetigsoLoaderOSGiFragmentTest(String name) {
super(name);
}

public void testNetigsoLoaderOSGiFragmentBundleSubstitution() throws Exception {

MockModuleInstaller installer = new MockModuleInstaller();
MockEvents ev = new MockEvents();
ModuleManager mgr = new ModuleManager(installer, ev);
mgr.mutexPrivileged().enterWriteAccess();
Set<Module> modules = new HashSet<Module>();

try {
File hostFile = changeManifest(new File(jars, "simple-module.jar"), HOST_MANIFEST);
File fragmentFile = changeManifest(new File(jars, "depends-on-simple-module.jar"), FRAGMENT_MANIFEST);
Module hostModule = mgr.create(hostFile, null, false, false, false);
Module fragmentModule = mgr.create(fragmentFile, null, false, false, false);
modules.addAll(Arrays.asList(hostModule, fragmentModule));
mgr.enable(modules);

NetigsoLoader hostLoader = getNetigsoLoaderForModule(hostModule);
NetigsoLoader fragmentLoader = getNetigsoLoaderForModule(fragmentModule);

assertEquals("NetigsoLoader in fragment module should use the host bundle",
hostLoader.getBundle(), fragmentLoader.getBundle());

} finally {
mgr.disable(modules);
mgr.mutexPrivileged().exitWriteAccess();
}
}

private NetigsoLoader getNetigsoLoaderForModule(Module module) throws Exception {
ClassLoader moduleClassLoader = module.getClassLoader();

// NetigsoModule wraps the class loader inside a private DelegateCL class,
// which delegates to the NetigsoLoader via delegate() method
Method delegate = moduleClassLoader.getClass().getDeclaredMethod("delegate");
delegate.setAccessible(true);
NetigsoLoader netigsoLoader = (NetigsoLoader) delegate.invoke(moduleClassLoader);
return netigsoLoader;
}

}

0 comments on commit 5f7d848

Please sign in to comment.