diff -r 87162b13ea2c o.n.bootstrap/manifest.mf --- a/o.n.bootstrap/manifest.mf Tue May 11 18:05:28 2010 +0200 +++ b/o.n.bootstrap/manifest.mf Wed May 12 14:10:17 2010 +0200 @@ -1,6 +1,6 @@ Manifest-Version: 1.0 OpenIDE-Module: org.netbeans.bootstrap/1 -OpenIDE-Module-Specification-Version: 2.32 +OpenIDE-Module-Specification-Version: 2.33 OpenIDE-Module-Localizing-Bundle: org/netbeans/Bundle.properties OpenIDE-Module-Recommends: org.netbeans.NetigsoFramework diff -r 87162b13ea2c o.n.bootstrap/src/org/netbeans/StandardModule.java --- a/o.n.bootstrap/src/org/netbeans/StandardModule.java Tue May 11 18:05:28 2010 +0200 +++ b/o.n.bootstrap/src/org/netbeans/StandardModule.java Wed May 12 14:10:17 2010 +0200 @@ -1,7 +1,7 @@ /* * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. * - * Copyright 1997-2009 Sun Microsystems, Inc. All rights reserved. + * Copyright 1997-2010 Sun Microsystems, Inc. All rights reserved. * * The contents of this file are subject to the terms of either the GNU * General Public License Version 2 only ("GPL") or the Common @@ -674,7 +674,7 @@ /** Class loader to load a single module. * Auto-localizing, multi-parented, permission-granting, the works. */ - private class OneModuleClassLoader extends JarClassLoader implements Util.ModuleProvider { + class OneModuleClassLoader extends JarClassLoader implements Util.ModuleProvider { private int rc; /** Create a new loader for a module. * @param classp the List of all module jars of code directories; @@ -700,15 +700,29 @@ return getAllPermission(); } - /** look for JNI libraries also in modules/bin/ */ + /** + * Look up a native library as described in modules documentation. + * @see http://bits.netbeans.org/dev/javadoc/org-openide-modules/org/openide/modules/doc-files/api.html#jni + */ protected @Override String findLibrary(String libname) { + String arch = System.getProperty("os.arch"); // NOI18N + String system = System.getProperty("os.name").toLowerCase(); // NOI18N String mapped = System.mapLibraryName(libname); - File lib = new File(new File(jar.getParentFile(), "lib"), mapped); // NOI18N - if (lib.isFile()) { - return lib.getAbsolutePath(); - } else { - return null; - } + + File base = new File(jar.getParentFile(), "lib"); // NOI18N + File archFile = new File(base, arch); + File systemFile = new File(archFile, system); + + File lib = new File(systemFile, mapped); + if (lib.isFile()) return lib.getAbsolutePath(); + + lib = new File(archFile, mapped); + if (lib.isFile()) return lib.getAbsolutePath(); + + lib = new File(base, mapped); + if (lib.isFile()) return lib.getAbsolutePath(); + + return null; } protected @Override boolean shouldDelegateResource(String pkg, ClassLoader parent) { diff -r 87162b13ea2c o.n.bootstrap/test/unit/src/org/netbeans/NativeLibraryTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/o.n.bootstrap/test/unit/src/org/netbeans/NativeLibraryTest.java Wed May 12 14:10:17 2010 +0200 @@ -0,0 +1,147 @@ +/* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + * + * Copyright 1997-2010 Sun Microsystems, Inc. All rights reserved. + * + * The contents of this file are subject to the terms of either the GNU + * General Public License Version 2 only ("GPL") or the Common + * Development and Distribution License("CDDL") (collectively, the + * "License"). You may not use this file except in compliance with the + * License. You can obtain a copy of the License at + * http://www.netbeans.org/cddl-gplv2.html + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the + * specific language governing permissions and limitations under the + * License. When distributing the software, include this License Header + * Notice in each file and include the License file at + * nbbuild/licenses/CDDL-GPL-2-CP. Sun designates this + * particular file as subject to the "Classpath" exception as provided + * by Sun in the GPL Version 2 section of the License file that + * accompanied this code. If applicable, add the following below the + * License Header, with the fields enclosed by brackets [] replaced by + * your own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * If you wish your version of this file to be governed by only the CDDL + * or only the GPL Version 2, indicate your decision by adding + * "[Contributor] elects to include this software in this distribution + * under the [CDDL or GPL Version 2] license." If you do not indicate a + * single choice of license, a recipient has the option to distribute + * your version of this file under either the CDDL, the GPL Version 2 or + * to extend the choice of license to its licensees as provided above. + * However, if you add GPL Version 2 code and therefore, elected the GPL + * Version 2 license, then the option applies only if the new code is + * made subject to such option by the copyright holder. + * + * Contributor(s): + * + * Portions Copyrighted 2010 Sun Microsystems, Inc. + */ + +package org.netbeans; + +import java.io.File; +import java.io.IOException; +import java.util.HashMap; +import java.util.Map; +import org.netbeans.junit.NbTestCase; + +/** + * A test covering native library lookup mechanism. + * @see http://bits.netbeans.org/dev/javadoc/org-openide-modules/org/openide/modules/doc-files/api.html#jni + * + * @author Petr Nejedly + */ +public class NativeLibraryTest extends NbTestCase { + private File userdir; + private File ide; + private File platform; + private File install; + + private File jar; + private Module module; + + File fullLib; + File archLib; + File commonLib; + + public NativeLibraryTest(String testName) { + super(testName); + } + + @Override + protected void setUp() throws Exception { + clearWorkDir(); + + String arch = System.getProperty("os.arch"); // NOI18N + String system = System.getProperty("os.name").toLowerCase(); // NOI18N + + install = new File(getWorkDir(), "install"); + platform = new File(install, "platform"); + ide = new File(install, "ide"); + userdir = new File(getWorkDir(), "tmp"); + + System.setProperty("netbeans.home", platform.getPath()); + System.setProperty("netbeans.dirs", ide.getPath()); + System.setProperty("netbeans.user", userdir.getPath()); + + jar = createModule("org.openide.sample", platform, + "OpenIDE-Module-Public-Packages", "-", + "OpenIDE-Module", "org.openide.sample" + ); + + // now create 3 libraries, full, arch and common + fullLib = createFakeLibrary(jar, arch, system, System.mapLibraryName("full")); + archLib = createFakeLibrary(jar, arch, System.mapLibraryName("arch")); + commonLib = createFakeLibrary(jar, arch, System.mapLibraryName("common")); + + MockModuleInstaller installer = new MockModuleInstaller(); + MockEvents ev = new MockEvents(); + ModuleManager mgr = new ModuleManager(installer, ev); + mgr.mutexPrivileged().enterWriteAccess(); + module = mgr.create(jar, null, false, false, false); + mgr.enable(module); + mgr.mutexPrivileged().exitWriteAccess(); + + } + + public void testLocateLibrary() { + // testing + StandardModule.OneModuleClassLoader ldr = (StandardModule.OneModuleClassLoader)module.getClassLoader(); + assertEquals(fullLib.getAbsolutePath(), ldr.findLibrary("full")); + assertEquals(archLib.getAbsolutePath(), ldr.findLibrary("arch")); + assertEquals(commonLib.getAbsolutePath(), ldr.findLibrary("common")); + assertNull(ldr.findLibrary("none")); + } + + private File createFakeLibrary(File jar, String... path) throws IOException { + File out = new File(jar.getParentFile(), "lib"); + for(String component : path) out = new File(out, component); + + // prepare the path + out.getParentFile().mkdirs(); + + out.createNewFile(); + return out; + } + + + private File createModule(String cnb, File cluster, String... attr) throws IOException { + String dashes = cnb.replace('.', '-'); + + File tmp = new File(new File(cluster, "modules"), dashes + ".jar"); + + Map attribs = new HashMap(); + for (int i = 0; i < attr.length; i += 2) { + attribs.put(attr[i], attr[i + 1]); + } + + Map files = new HashMap(); + files.put("fake/" + cnb, cnb); + + tmp.getParentFile().mkdirs(); + SetupHid.createJar(tmp, files, attribs); + + return tmp; + } + +}