diff -r 3a5fbd8a8404 core.startup/apichanges.xml --- a/core.startup/apichanges.xml Thu Oct 07 19:31:43 2010 +0200 +++ b/core.startup/apichanges.xml Mon Oct 11 13:33:58 2010 +0200 @@ -56,6 +56,21 @@ + + + netbeans.bootdelegation property + + + + + +

+ New property + netbeans.bootdelegation + is available. +

+
+
Environment variables are no longer accessible through system properties diff -r 3a5fbd8a8404 core.startup/arch.xml --- a/core.startup/arch.xml Thu Oct 07 19:31:43 2010 +0200 +++ b/core.startup/arch.xml Mon Oct 11 13:33:58 2010 +0200 @@ -600,6 +600,26 @@ Allows unit tests to prevent changes to System.err and System.out by the logging infrastructure. + +

+ Similar to OSGi's org.osgi.framework.bootdelegation property. + Allows unit tests (or even regular code) to prevent classloading from + application classloader for other, then explicitly enumerated packages. +

+

+ This property shall contain a set of comma separated values of + package names. Classes from those packages will be loaded by the + classloader framework from application classloader. If the name of + a package ends with .* suffix, all packages under the + given package name are allowed for delegation (but not the package by itself). +

+

+ The classes from the java.* namespace are allowed + and do not need to be enumerated at all. If this property is not + specified at all, all classes visible by the application classloader + can be accessed. Available since version 1.26. +

+

diff -r 3a5fbd8a8404 core.startup/manifest.mf --- a/core.startup/manifest.mf Thu Oct 07 19:31:43 2010 +0200 +++ b/core.startup/manifest.mf Mon Oct 11 13:33:58 2010 +0200 @@ -3,5 +3,5 @@ OpenIDE-Module-Localizing-Bundle: org/netbeans/core/startup/Bundle.properties OpenIDE-Module-Layer: org/netbeans/core/startup/layer.xml OpenIDE-Module-Provides: org.openide.modules.InstalledFileLocator -OpenIDE-Module-Specification-Version: 1.25 +OpenIDE-Module-Specification-Version: 1.26 diff -r 3a5fbd8a8404 core.startup/src/org/netbeans/core/startup/NbInstaller.java --- a/core.startup/src/org/netbeans/core/startup/NbInstaller.java Thu Oct 07 19:31:43 2010 +0200 +++ b/core.startup/src/org/netbeans/core/startup/NbInstaller.java Mon Oct 11 13:33:58 2010 +0200 @@ -817,6 +817,9 @@ } } } + if (!checkBootDelegation(pkg)) { + return false; + } } if (LOG.isLoggable(Level.FINER) && /* otherwise ClassCircularityError on LogRecord*/!pkg.equals("java/util/logging/")) { LOG.finer("Delegating resource " + pkg + " from " + parent + " for " + m.getCodeNameBase()); @@ -840,6 +843,35 @@ } } } + return checkBootDelegation(pkg); + } + + private boolean checkBootDelegation(String pkg) { + String del = System.getProperty("netbeans.bootdelegation"); // NOI18N + if (del != null) { + if (!pkg.startsWith("java/")) { + boolean allowed = false; + for (String s : del.split(",")) { + s = s.trim(); + if (s.endsWith(".*")) { + s = s.substring(0, s.length() - 2).replace('.', '/') + '/'; + if (pkg.startsWith(s) && pkg.length() > s.length()) { + allowed = true; + break; + } + } else { + s = s.replace('.', '/') + '/'; + if (pkg.equals(s)) { + allowed = true; + break; + } + } + } + if (!allowed) { + return false; + } + } + } return true; } diff -r 3a5fbd8a8404 core.startup/test/unit/src/org/netbeans/core/startup/NbBootDelegationTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/core.startup/test/unit/src/org/netbeans/core/startup/NbBootDelegationTest.java Mon Oct 11 13:33:58 2010 +0200 @@ -0,0 +1,89 @@ +/* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + * + * Copyright 2010 Oracle and/or its affiliates. All rights reserved. + * + * Oracle and Java are registered trademarks of Oracle and/or its affiliates. + * Other names may be trademarks of their respective owners. + * + * 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. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle 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.core.startup; + +import java.io.File; +import java.util.Collections; +import org.netbeans.Module; +import org.netbeans.ModuleManager; + +/** + * + * @author Jaroslav Tulach + */ +public class NbBootDelegationTest extends NbInstallerTestBase { + + public NbBootDelegationTest(String n) { + super(n); + } + + public void testNetBeansBootDelegation() throws Exception { + ModuleManager mgr = Main.getModuleSystem().getManager(); + mgr.mutexPrivileged().enterWriteAccess(); + System.setProperty("netbeans.bootdelegation", "javax.swing, javax.naming.*"); + try { + Module m1 = mgr.create(new File(jars, "simple-module.jar"), null, false, false, false); + mgr.enable(Collections.singleton(m1)); + final ClassLoader ldr = m1.getClassLoader(); + Class jtree = Class.forName("javax.swing.JTree", true, ldr); + assertNotNull("JTree found", jtree); + String tableModel = "javax.swing.table.TableModel"; + try { + Class model = Class.forName(tableModel, true, ldr); + fail("Model shall not be accessible: " + model); + } catch (ClassNotFoundException ex) { + // OK + assertNotNull("The class exists on boot path", ClassLoader.getSystemClassLoader().loadClass(tableModel)); + } + Class list = Class.forName("java.util.ArrayList", true, ldr); + assertNotNull("java packages are always accessible", list); + Class naming = Class.forName("javax.naming.event.EventContext", true, ldr); + assertNotNull("naming is recursively visible", naming); + } finally { + System.getProperties().remove("netbeans.bootdelegation"); + mgr.mutexPrivileged().exitWriteAccess(); + } + } + + +}