/******************************************************************************* * Copyright (c) 2013 IBM Corporation and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * and Eclipse Distribution License v1.0 which accompany this distribution. * The Eclipse Public License is available at * http://www.eclipse.org/legal/epl-v10.html * and the Eclipse Distribution License is available at * http://www.eclipse.org/org/documents/edl-v10.php. * * Contributors: * Jochen Hiller *******************************************************************************/ package org.eclipse.concierge; import java.util.HashMap; import org.eclipse.concierge.test.util.AbstractConciergeTestCase; import org.eclipse.concierge.test.util.SyntheticBundleBuilder; import org.junit.After; import org.junit.Assert; import org.junit.Test; import org.osgi.framework.Bundle; import org.osgi.framework.BundleException; import org.osgi.framework.Constants; /** * Tests parent class loader configurations. We use a javafx class and a * com.sun.crypt.provider classes as they will be loaded as an extension from * lib/jre/ext folder. * * @author Jochen Hiller - Initial contribution */ public class ConciergeParentClassLoader extends AbstractConciergeTestCase { private Bundle bundleUnderTest; @After public void tearDown() throws Exception { stopFramework(); } private void setupJavaFxBundle() throws BundleException { SyntheticBundleBuilder builder = new SyntheticBundleBuilder(); builder.bundleSymbolicName("bundle").addManifestHeader( "Import-Package", "javafx.application"); bundleUnderTest = installBundle(builder); bundleUnderTest.start(); assertBundleActive(bundleUnderTest); } private boolean isJavaFxAvailable() { try { ClassLoader.getSystemClassLoader().loadClass( "javafx.application.Application"); return true; } catch (ClassNotFoundException e) { return false; } } @Test public void testLoadClassJavaFxWithParentClassLoader() throws Exception { if (!isJavaFxAvailable()) { System.err .println("Skipping testLoadClassJavaFxWithParentClassLoader: javafx not available"); return; } HashMap<String, String> launchArgs = new HashMap<String, String>(); // launchArgs.put(Constants.FRAMEWORK_BOOTDELEGATION, "javafx.*"); launchArgs.put(Constants.FRAMEWORK_BUNDLE_PARENT, Constants.FRAMEWORK_BUNDLE_PARENT_EXT); launchArgs.put(Constants.FRAMEWORK_SYSTEMPACKAGES_EXTRA, "javafx.application"); startFrameworkClean(launchArgs); setupJavaFxBundle(); RunInClassLoader runner = new RunInClassLoader(bundleUnderTest); // as javafx is loaded from ext class loader it has to work now Class<?> clazz = runner.getClass("javafx.application.Application"); // and loaded class has to be identical to one loaded from system class // loader Class<?> clazzFromSystemClassLoader = ClassLoader .getSystemClassLoader().loadClass( "javafx.application.Application"); Assert.assertEquals(clazzFromSystemClassLoader, clazz); Assert.assertTrue(clazz == clazzFromSystemClassLoader); } /** * Installs a bundle with an import to a package in an library in lib/ext * (here: sunjce_provider.jar). */ private void setupSunJceBundle() throws BundleException { SyntheticBundleBuilder builder = new SyntheticBundleBuilder(); builder.bundleSymbolicName("bundle").addManifestHeader( "Import-Package", "com.sun.crypto.provider"); bundleUnderTest = installBundle(builder); bundleUnderTest.start(); assertBundleActive(bundleUnderTest); } /** * Loads a class from a lib/ext library via BOOT classloader, will NOT work. */ @Test public void testLoadClassFromLibExtWithBootParentClassLoader() throws Exception { loadClassFailedFromLibExtWithParentClassLoader(Constants.FRAMEWORK_BUNDLE_PARENT_BOOT); } /** * Loads a class from a lib/ext library via APP classloader, will work, as * app class loader inherits standard class loader which include ext class * loader. */ @Test public void testLoadClassFromLibExtWithAppParentClassLoader() throws Exception { loadClassSuccessfulFromLibExtWithParentClassLoader(Constants.FRAMEWORK_BUNDLE_PARENT_APP); } /** * Loads a class from a lib/ext library via FRAMEWORK classloader, will * work, as framework class loader inherits standard class loader which * include ext class loader. */ @Test public void testLoadClassFromLibExtWithFrameworkParentClassLoader() throws Exception { loadClassSuccessfulFromLibExtWithParentClassLoader(Constants.FRAMEWORK_BUNDLE_PARENT_FRAMEWORK); } /** * Loads a class from a lib/ext library via EXT classloader, will work, as * lib/ext will found by this class loader. */ @Test public void testLoadClassFromLibExtWithExtParentClassLoader() throws Exception { loadClassSuccessfulFromLibExtWithParentClassLoader(Constants.FRAMEWORK_BUNDLE_PARENT_EXT); } // helper methods public void loadClassFailedFromLibExtWithParentClassLoader( String parentClassLoader) throws Exception { HashMap<String, String> launchArgs = new HashMap<String, String>(); launchArgs.put(Constants.FRAMEWORK_BUNDLE_PARENT, parentClassLoader); launchArgs.put(Constants.FRAMEWORK_SYSTEMPACKAGES_EXTRA, "com.sun.crypto.provider"); startFrameworkClean(launchArgs); setupSunJceBundle(); RunInClassLoader runner = new RunInClassLoader(bundleUnderTest); try { runner.getClass("com.sun.crypto.provider.HmacSHA1"); Assert.fail("Uups, ClassNotFoundException expected"); } catch (ClassNotFoundException ex) { // OK, expected } } private void loadClassSuccessfulFromLibExtWithParentClassLoader( String parentClassLoader) throws Exception { HashMap<String, String> launchArgs = new HashMap<String, String>(); launchArgs.put(Constants.FRAMEWORK_BUNDLE_PARENT, parentClassLoader); launchArgs.put(Constants.FRAMEWORK_SYSTEMPACKAGES_EXTRA, "com.sun.crypto.provider"); startFrameworkClean(launchArgs); setupSunJceBundle(); RunInClassLoader runner = new RunInClassLoader(bundleUnderTest); Class<?> clazz = runner.getClass("com.sun.crypto.provider.HmacSHA1"); // loaded class has to be identical to one loaded from system class // loader Class<?> clazzFromSystemClassLoader = ClassLoader .getSystemClassLoader().loadClass( "com.sun.crypto.provider.HmacSHA1"); Assert.assertEquals(clazzFromSystemClassLoader, clazz); Assert.assertTrue(clazz == clazzFromSystemClassLoader); } }