[jboss-cvs] JBossAS SVN: r97150 - in projects/embedded/trunk: api/src/main/java/org/jboss/embedded/api/server and 9 other directories.
jboss-cvs-commits at lists.jboss.org
jboss-cvs-commits at lists.jboss.org
Mon Nov 30 00:42:18 EST 2009
Author: ALRubinger
Date: 2009-11-30 00:42:18 -0500 (Mon, 30 Nov 2009)
New Revision: 97150
Added:
projects/embedded/trunk/api/src/main/java/org/jboss/embedded/api/server/JBossHomeClassLoader.java
projects/embedded/trunk/testsuite-jbosshomecl/
projects/embedded/trunk/testsuite-jbosshomecl/pom.xml
projects/embedded/trunk/testsuite-jbosshomecl/src/
projects/embedded/trunk/testsuite-jbosshomecl/src/test/
projects/embedded/trunk/testsuite-jbosshomecl/src/test/java/
projects/embedded/trunk/testsuite-jbosshomecl/src/test/java/org/
projects/embedded/trunk/testsuite-jbosshomecl/src/test/java/org/jboss/
projects/embedded/trunk/testsuite-jbosshomecl/src/test/java/org/jboss/embedded/
projects/embedded/trunk/testsuite-jbosshomecl/src/test/java/org/jboss/embedded/testsuite/
projects/embedded/trunk/testsuite-jbosshomecl/src/test/java/org/jboss/embedded/testsuite/jbosshomecl/
projects/embedded/trunk/testsuite-jbosshomecl/src/test/java/org/jboss/embedded/testsuite/jbosshomecl/JBossHomeClassLoaderIntegrationTest.java
Modified:
projects/embedded/trunk/pom.xml
Log:
[EMB-73] Create a mechanism (custom ClassLoader) and testsuite allowing AS to be booted with a very minimal dependency set upon the application classpath, and the rest coming in from JBOSS_HOME
Added: projects/embedded/trunk/api/src/main/java/org/jboss/embedded/api/server/JBossHomeClassLoader.java
===================================================================
--- projects/embedded/trunk/api/src/main/java/org/jboss/embedded/api/server/JBossHomeClassLoader.java (rev 0)
+++ projects/embedded/trunk/api/src/main/java/org/jboss/embedded/api/server/JBossHomeClassLoader.java 2009-11-30 05:42:18 UTC (rev 97150)
@@ -0,0 +1,232 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2009, Red Hat Middleware LLC, and individual contributors
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * Licensed 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.jboss.embedded.api.server;
+
+import java.io.File;
+import java.net.MalformedURLException;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.net.URL;
+import java.net.URLClassLoader;
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.Set;
+import java.util.logging.Logger;
+
+/**
+ * {@link ClassLoader} implementation which is capable of booting
+ * the JBoss Application Server installation located at a known
+ * $JBOSS_HOME
+ *
+ * @author <a href="mailto:andrew.rubinger at jboss.org">ALR</a>
+ * @version $Revision: $
+ */
+public class JBossHomeClassLoader extends URLClassLoader
+{
+
+ //-------------------------------------------------------------------------------------||
+ // Class Members ----------------------------------------------------------------------||
+ //-------------------------------------------------------------------------------------||
+
+ /**
+ * Logger
+ */
+ private static final Logger log = Logger.getLogger(JBossHomeClassLoader.class.getName());
+
+ /**
+ * Name of the boot library directory, relative to $JBOSS_HOME
+ */
+ private static final String DIR_NAME_LIB = "lib/";
+
+ /**
+ * Libraries, relative to $JBOSS_HOME/lib, which must be visible to
+ * the context ClassLoader (and the loading CL of the server)
+ * in order to boot the Application Server. This is a carefully
+ * pruned list in order to not leak out class references, which would
+ * in turn result in {@link NoClassDefFoundError}
+ */
+ public static final String[] JBOSS_LIB_BOOT_LIST =
+ {
+ // Concurrent
+ "concurrent.jar",
+ // Logging
+ "log4j-boot.jar",
+ "jboss-logging-spi.jar",
+ "jboss-logging-log4j.jar",
+ "jboss-logging-jdk.jar",
+ "jboss-logmanager.jar",
+ "jboss-logbridge.jar",
+ // Common jars
+ "jboss-common-core.jar",
+ "jboss-xml-binding.jar",
+ // Bootstrap
+ "jboss-bootstrap-spi.jar", "jboss-bootstrap-spi-as.jar", "jboss-bootstrap-spi-mc.jar",
+ "jboss-bootstrap-impl-base.jar", "jboss-bootstrap-impl-as.jar", "jboss-bootstrap-impl-mc.jar",
+ "jboss-bootstrap-api-as.jar", "jboss-bootstrap-api-mc.jar",
+ "jboss-bootstrap-api.jar",
+ // Microcontainer
+ "javassist.jar", "jboss-reflect.jar", "jboss-mdr.jar", "jboss-dependency.jar", "jboss-kernel.jar",
+ "jboss-metatype.jar", "jboss-managed.jar",
+ // Deployers
+ "jboss-deployers-core-spi.jar", "jboss-deployers-client-spi.jar",
+ // Fixme ClassLoading
+ "jboss-vfs.jar", "jboss-classloading-spi.jar", "jboss-classloader.jar", "jboss-classloading.jar",
+ "jboss-classloading-vfs.jar",
+ // Fixme aop
+ "jboss-aop.jar", "jboss-aop-mc-int.jar", "trove.jar"};
+
+ /**
+ * Libraries, relative to $JBOSS_HOME/bin, which must be visible to
+ * the context ClassLoader (and the loading CL of the server)
+ * in order to boot the Application Server. This is a carefully
+ * pruned list in order to not leak out class references, which would
+ * in turn result in {@link NoClassDefFoundError}
+ */
+ public static final String[] JBOSS_BIN_BOOT_LIST =
+ {"run.jar"};
+
+ //-------------------------------------------------------------------------------------||
+ // Constructor ------------------------------------------------------------------------||
+ //-------------------------------------------------------------------------------------||
+
+ /**
+ * Constructs a new instance using the specified URLs; not exposed publicly, instead use
+ * {@link JBossHomeClassLoader#newInstance(URL, URL[])} outside this class
+ */
+ private JBossHomeClassLoader(final URL[] urls, final ClassLoader parent) throws IllegalArgumentException,
+ IllegalStateException
+ {
+ // Invoke super
+ super(urls, parent);
+ }
+
+ //-------------------------------------------------------------------------------------||
+ // Factory Methods --------------------------------------------------------------------||
+ //-------------------------------------------------------------------------------------||
+
+ /**
+ * Constructs a new instance, using the required boot libraries of the specified $JBOSS_HOME
+ * as well as the the additional URLs specified (optional)
+ *
+ * @param jbossHome The location to JBOSS_HOME
+ * @param urls Additional URLs which this ClassLoader should use; may be null
+ * @param parent The parent to assign to the new ClassLoader
+ */
+ public static JBossHomeClassLoader newInstance(final URL jbossHome, final URL[] urls, final ClassLoader parent)
+ {
+ // Get $JBOSS_HOME/lib URLs
+ final URL[] jbossLibBootUrls = getJBossLibBootUrls(jbossHome);
+
+ // Merge with the specified URLs passed in
+ final URL[] merged = merge(jbossLibBootUrls, urls);
+
+ // Create and return a new instance
+ return new JBossHomeClassLoader(merged, parent);
+ }
+
+ //-------------------------------------------------------------------------------------||
+ // Internal Helper Methods ------------------------------------------------------------||
+ //-------------------------------------------------------------------------------------||
+
+ /**
+ * Merges the arrays of all URLs into a unified view, with no duplicate
+ * elements
+ *
+ * @param urls Any number of arrays to be represented as a union
+ * @throws IllegalArgumentException If the URLs specified are null
+ */
+ private static URL[] merge(final URL[]... urls) throws IllegalArgumentException
+ {
+ // Precondition check
+ assert urls != null : "URLs must be specified";
+
+ // Create a set
+ final Set<URL> urlSet = new HashSet<URL>();
+
+ // Merge
+ for (final URL[] current : urls)
+ {
+ for (final URL single : current)
+ {
+ urlSet.add(single);
+ }
+ }
+
+ // Return
+ return urlSet.toArray(new URL[]
+ {});
+
+ }
+
+ /**
+ * Obtains all boot libraries for which ClassLoader
+ * visibility is required given the specified $JBOSS_HOME
+ */
+ private static URL[] getJBossLibBootUrls(final URL jbossHome)
+ {
+ // Get a URL to $JBOSS_HOME/lib
+ final URL jbossLib;
+ try
+ {
+ jbossLib = new URL(jbossHome, DIR_NAME_LIB);
+ }
+ catch (final MalformedURLException murle)
+ {
+ throw new RuntimeException("Error in constructing $JBOSS_HOME/lib URL", murle);
+ }
+
+ final Collection<URL> urls = new HashSet<URL>();
+ // Add all appropriate JBOSS_HOME/lib binaries
+ for (final String bootLib : JBOSS_LIB_BOOT_LIST)
+ {
+ final URL url;
+ try
+ {
+ url = new URL(jbossLib, bootLib);
+ }
+ catch (final MalformedURLException murle)
+ {
+ throw new RuntimeException("Could not construct full URL for $JBOSS_HOME boot library: " + bootLib, murle);
+ }
+ urls.add(url);
+ log.finer("Using: " + url);
+
+ // Check file for existence
+ final URI uri;
+ try
+ {
+ uri = url.toURI();
+ }
+ catch (final URISyntaxException urise)
+ {
+ throw new RuntimeException(urise);
+ }
+ final File file = new File(uri);
+ if (!file.exists())
+ {
+ throw new IllegalStateException("Attempting to add a library to the ClassLoader which does not exist: "
+ + file + "; perhaps a corrupt $JBOSS_HOME installation? ");
+ }
+ }
+
+ // Return
+ log.fine("Using: " + urls);
+ return urls.toArray(new URL[]
+ {});
+ }
+
+}
Modified: projects/embedded/trunk/pom.xml
===================================================================
--- projects/embedded/trunk/pom.xml 2009-11-30 05:05:43 UTC (rev 97149)
+++ projects/embedded/trunk/pom.xml 2009-11-30 05:42:18 UTC (rev 97150)
@@ -42,6 +42,7 @@
<module>core</module>
<module>depchain</module>
<module>testsuite</module>
+ <module>testsuite-jbosshomecl</module>
</modules>
</project>
Property changes on: projects/embedded/trunk/testsuite-jbosshomecl
___________________________________________________________________
Name: svn:ignore
+ target
eclipse-target
target-eclipse
bin
.settings
.classpath
.project
Added: projects/embedded/trunk/testsuite-jbosshomecl/pom.xml
===================================================================
--- projects/embedded/trunk/testsuite-jbosshomecl/pom.xml (rev 0)
+++ projects/embedded/trunk/testsuite-jbosshomecl/pom.xml 2009-11-30 05:42:18 UTC (rev 97150)
@@ -0,0 +1,138 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+
+ <!-- Parent -->
+ <parent>
+ <groupId>org.jboss.embedded</groupId>
+ <artifactId>jboss-embedded-build</artifactId>
+ <version>1.0.0-SNAPSHOT</version>
+ <relativePath>../build/pom.xml</relativePath>
+ </parent>
+
+ <!-- Model Version -->
+ <modelVersion>4.0.0</modelVersion>
+
+ <!-- Artifact Configuration -->
+ <artifactId>jboss-embedded-testsuite-jbosshomecl</artifactId>
+ <name>JBossAS Embedded TestSuite using JBOSS_HOME ClassLoading</name>
+ <description>JBoss Application Server Embedded TestSuite for JBOSS_HOME ClassLoading</description>
+
+ <!-- Properties -->
+ <properties>
+
+ <!-- JBOSS_HOME (We'll unpack into here -->
+ <JBOSS_HOME>${project.build.directory}/jboss-as-distribution-${version.org.jboss.jbossas}</JBOSS_HOME>
+
+ <!-- Versioning -->
+
+ </properties>
+
+ <!-- Build Configuration -->
+ <build>
+
+ <plugins>
+
+ <!-- Surefire -->
+ <plugin>
+ <artifactId>maven-surefire-plugin</artifactId>
+ <executions>
+ <execution>
+ <id>integration-test</id>
+ <phase>integration-test</phase>
+ <goals>
+ <goal>test</goal>
+ </goals>
+ <configuration>
+ <additionalClasspathElements>
+ <additionalClasspathElement>${JBOSS_HOME}/bin/run.jar</additionalClasspathElement>
+ </additionalClasspathElements>
+ <redirectTestOutputToFile>true</redirectTestOutputToFile>
+ <trimStackTrace>false</trimStackTrace>
+ <printSummary>true</printSummary>
+ <includes>
+ <include>**/*IntegrationTest.java</include>
+ </includes>
+ <forkMode>always</forkMode>
+ <argLine>-XX:MaxPermSize=256m -Djava.net.preferIPv4Stack=true -Djava.endorsed.dirs=${JBOSS_HOME}/lib/endorsed -Djboss.home=${JBOSS_HOME}</argLine>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
+
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-dependency-plugin</artifactId>
+ <executions>
+ <!-- Get AS and put into "target" -->
+ <execution>
+ <id>unpack</id>
+ <phase>pre-integration-test</phase> <!-- So run before testing -->
+ <goals>
+ <goal>unpack</goal>
+ </goals>
+ <configuration>
+ <artifactItems>
+ <artifactItem>
+ <groupId>org.jboss.jbossas</groupId>
+ <artifactId>jboss-as-distribution</artifactId>
+ <version>${version.org.jboss.jbossas}</version>
+ <type>zip</type>
+ <overWrite>false</overWrite>
+ <outputDirectory>${project.build.directory}</outputDirectory>
+ </artifactItem>
+ </artifactItems>
+ </configuration>
+ </execution>
+ <!-- Other deps, not part of AS, into "target/deps" -->
+ <execution>
+ <id>copy</id>
+ <phase>pre-integration-test</phase>
+ <goals>
+ <goal>copy</goal>
+ </goals>
+ <configuration>
+ <artifactItems>
+ <artifactItem>
+ <groupId>org.jboss.embedded</groupId>
+ <artifactId>jboss-embedded-core</artifactId>
+ <version>${version}</version>
+ <overWrite>false</overWrite>
+ <outputDirectory>${project.build.directory}/deps</outputDirectory>
+ </artifactItem>
+ </artifactItems>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
+
+ </build>
+
+ <!-- Dependencies -->
+ <dependencies>
+
+ <!--
+
+ Here we define an ultra-minimal dependency set; just enough to
+ compile/load the test class (ie. EmbeddedAS API only). In the test
+ we'll use a URL ClassLoader to get the necessary libraries from
+ JBOSS_HOME and launch from there.
+ -->
+
+ <dependency>
+ <groupId>org.jboss.embedded</groupId>
+ <artifactId>jboss-embedded-api</artifactId>
+ <version>${version}</version>
+ <scope>test</scope>
+ </dependency>
+
+ <!-- JUnit -->
+ <dependency>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ </dependency>
+
+ </dependencies>
+
+</project>
Added: projects/embedded/trunk/testsuite-jbosshomecl/src/test/java/org/jboss/embedded/testsuite/jbosshomecl/JBossHomeClassLoaderIntegrationTest.java
===================================================================
--- projects/embedded/trunk/testsuite-jbosshomecl/src/test/java/org/jboss/embedded/testsuite/jbosshomecl/JBossHomeClassLoaderIntegrationTest.java (rev 0)
+++ projects/embedded/trunk/testsuite-jbosshomecl/src/test/java/org/jboss/embedded/testsuite/jbosshomecl/JBossHomeClassLoaderIntegrationTest.java 2009-11-30 05:42:18 UTC (rev 97150)
@@ -0,0 +1,164 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2009, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.embedded.testsuite.jbosshomecl;
+
+import java.io.File;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.util.HashSet;
+import java.util.Set;
+import java.util.logging.Logger;
+
+import junit.framework.TestCase;
+
+import org.jboss.bootstrap.api.lifecycle.LifecycleState;
+import org.jboss.embedded.api.server.JBossASEmbeddedServer;
+import org.jboss.embedded.api.server.JBossASEmbeddedServerFactory;
+import org.jboss.embedded.api.server.JBossHomeClassLoader;
+import org.junit.Test;
+
+/**
+ * Test Cases to ensure that the JBossAS Server may
+ * be booted via the Embedded APIs using a minimal
+ * dependency set upon the classpath, bolstered
+ * by the {@link JBossHomeClassLoader} to make the rest of
+ * the binaries visible for a full boot.
+ *
+ * @author <a href="mailto:andrew.rubinger at jboss.org">ALR</a>
+ * @version $Revision: $
+ */
+public class JBossHomeClassLoaderIntegrationTest
+{
+
+ //-------------------------------------------------------------------------------||
+ // Class Members ----------------------------------------------------------------||
+ //-------------------------------------------------------------------------------||
+
+ /**
+ * Logger
+ */
+ private static final Logger log = Logger.getLogger(JBossHomeClassLoaderIntegrationTest.class.getName());
+
+ /**
+ * The server instance
+ */
+ private static JBossASEmbeddedServer server;
+
+ /**
+ * Name of the server configuration to use
+ */
+ private static final String NAME_SERVER_CONFIG = "all";
+
+ //-------------------------------------------------------------------------------||
+ // Tests ------------------------------------------------------------------------||
+ //-------------------------------------------------------------------------------||
+
+ /**
+ * Tests that we can start up and shut down cleanly using a minimal
+ * dependency set, and the {@link JBossHomeClassLoader} to bring
+ * in the required visibility
+ */
+ @Test
+ public void startEmbeddedUsingJBossHomeClassLoader() throws Exception
+ {
+ // Get JBOSS_HOME
+ final URL jbossHome = this.getJBossHome();
+
+ // Get additional binaries which need CL visibility (ie. jboss-embedded-core,
+ // which is placed under "target/deps" by the build). These
+ // binaries are not presently available under $JBOSS_HOME
+ final Set<URL> additionalUrls = new HashSet<URL>();
+ final URL source = this.getClass().getProtectionDomain().getCodeSource().getLocation();
+ final URL target = new URL(source, "..");
+ final URL additionalDeps = new URL(target, "deps");
+ final File deps = new File(additionalDeps.toURI());
+ TestCase.assertTrue("Dependencies location does not exist: " + deps, deps.exists());
+ TestCase.assertTrue("Dependencies location is not a directory: " + deps, deps.isDirectory());
+ for (final File child : deps.listFiles())
+ {
+ additionalUrls.add(child.toURI().toURL());
+ log.info("Booting with: " + child);
+ }
+
+ // Make the new ClassLoader
+ final ClassLoader oldCl = Thread.currentThread().getContextClassLoader();
+ final ClassLoader jbossHomeClassLoader = JBossHomeClassLoader.newInstance(jbossHome, additionalUrls
+ .toArray(new URL[]
+ {}), oldCl);
+
+ // Make Server
+ server = JBossASEmbeddedServerFactory.createServer(jbossHomeClassLoader);
+ log.info("Created: " + server);
+
+ // Start
+ log.info("Starting Server: " + server);
+ server.getConfiguration().serverName(NAME_SERVER_CONFIG);
+
+ // Set TCCL
+ Thread.currentThread().setContextClassLoader(jbossHomeClassLoader);
+
+ try
+ {
+ // Start the Server
+ server.start();
+ log.info("...started.");
+
+ // Test
+ TestCase.assertEquals("Server did not report started as expected", LifecycleState.STARTED, server.getState());
+
+ // Shutdown if started
+ if (server != null && server.getState().equals(LifecycleState.STARTED))
+ {
+ // Shutdown
+ log.info("Shutting down server: " + server);
+ server.shutdown();
+ }
+ }
+ finally
+ {
+ // Reset the TCCL
+ Thread.currentThread().setContextClassLoader(oldCl);
+ }
+ }
+
+ //-------------------------------------------------------------------------------||
+ // Internal Helper Methods ------------------------------------------------------||
+ //-------------------------------------------------------------------------------||
+
+ /**
+ * Obtains $JBOSS_HOME from the system property
+ *
+ * @return
+ */
+ private URL getJBossHome()
+ {
+ try
+ {
+ return new File(System.getProperty("jboss.home")).toURI().toURL();
+ }
+ catch (final MalformedURLException murle)
+ {
+ throw new RuntimeException("Could not get JBOSS_HOME", murle);
+ }
+ }
+
+}
More information about the jboss-cvs-commits
mailing list