mcconnell 2003/08/16 17:51:57
Modified: merlin/kernel/bootstrap project.xml
merlin/kernel/bootstrap/src/java Merlin.java
merlin/kernel/impl/src/java/org/apache/avalon/merlin/kernel/impl
CLIKernelLoader.java DefaultKernel.java
DefaultKernelContext.java
merlin/merlin-platform/src/config wrapper.conf
merlin/repository/impl/src/java/org/apache/avalon/repository/impl
DefaultFileRepository.java
Added: merlin/kernel/bootstrap/src/etc merlin.properties
Removed: merlin/kernel/bootstrap/src/java merlin.properties
Log:
Updates to the kernel bootstrap to address a bug identified by [EMAIL PROTECTED]
Changes also include the addition of facilities supporting proxy configuration within
the kernel configuration.
Revision Changes Path
1.2 +8 -0 avalon-sandbox/merlin/kernel/bootstrap/project.xml
Index: project.xml
===================================================================
RCS file: /home/cvs/avalon-sandbox/merlin/kernel/bootstrap/project.xml,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- project.xml 11 Aug 2003 22:34:45 -0000 1.1
+++ project.xml 17 Aug 2003 00:51:57 -0000 1.2
@@ -38,6 +38,14 @@
<unitTest></unitTest>
<testResources></testResources>
<integrationUnitTestPatterns></integrationUnitTestPatterns>
+ <resources>
+ <resource>
+ <directory>${basedir}/src/etc</directory>
+ <includes>
+ <include>merlin.properties</include>
+ </includes>
+ </resource>
+ </resources>
<jars></jars>
1.1 avalon-sandbox/merlin/kernel/bootstrap/src/etc/merlin.properties
Index: merlin.properties
===================================================================
#
# the bootstrap kernel loader class
#
merlin.bootstrap.class=org.apache.avalon.merlin.kernel.impl.CLIKernelLoader
#
# the bootstrap classpath
#
merlin.bootstrap.classpath.length=22
merlin.bootstrap.classpath.0=xerces:xerces;2.2.1
merlin.bootstrap.classpath.1=xml-apis:xml-apis;1.0.b2
merlin.bootstrap.classpath.2=avalon-framework:avalon-framework-api;SNAPSHOT
merlin.bootstrap.classpath.3=avalon-meta:avalon-meta-api;SNAPSHOT
merlin.bootstrap.classpath.4=avalon-meta:avalon-meta-spi;SNAPSHOT
merlin.bootstrap.classpath.5=avalon-extension:avalon-extension-spi;SNAPSHOT
merlin.bootstrap.classpath.6=avalon-composition:avalon-composition-spi;SNAPSHOT
merlin.bootstrap.classpath.7=avalon-activation:avalon-activation-spi;SNAPSHOT
merlin.bootstrap.classpath.8=avalon-framework:avalon-framework-impl;SNAPSHOT
merlin.bootstrap.classpath.9=avalon-meta:avalon-meta-impl;SNAPSHOT
merlin.bootstrap.classpath.10=avalon-extension:avalon-extension-impl;SNAPSHOT
merlin.bootstrap.classpath.11=avalon-composition:avalon-composition-impl;SNAPSHOT
merlin.bootstrap.classpath.12=avalon-activation:avalon-activation-impl;SNAPSHOT
merlin.bootstrap.classpath.13=excalibur-i18n:excalibur-i18n;1.0
merlin.bootstrap.classpath.14=avalon-repository:avalon-repository-spi;SNAPSHOT
merlin.bootstrap.classpath.15=avalon-repository:avalon-repository-impl;SNAPSHOT
merlin.bootstrap.classpath.16=commons-cli:commons-cli;1.0
merlin.bootstrap.classpath.17=merlin:merlin-kernel-spi;SNAPSHOT
merlin.bootstrap.classpath.18=merlin:merlin-kernel-impl;SNAPSHOT
merlin.bootstrap.classpath.19=logkit:logkit;1.2
merlin.bootstrap.classpath.20=excalibur-event:excalibur-event;1.0.3
merlin.bootstrap.classpath.21=excalibur:excalibur-configuration;1.0
1.3 +58 -12 avalon-sandbox/merlin/kernel/bootstrap/src/java/Merlin.java
Index: Merlin.java
===================================================================
RCS file: /home/cvs/avalon-sandbox/merlin/kernel/bootstrap/src/java/Merlin.java,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -r1.2 -r1.3
--- Merlin.java 12 Aug 2003 05:30:44 -0000 1.2
+++ Merlin.java 17 Aug 2003 00:51:57 -0000 1.3
@@ -87,6 +87,8 @@
"merlin.repository.remote";
private static final String MERLIN_BOOTSTRAP_CLASSNAME_KEY =
"merlin.bootstrap.class";
+ private static final String MERLIN_BOOTSTRAP_CLASSPATH_LENGTH_KEY =
+ "merlin.bootstrap.classpath.length";
private static final String MERLIN_BOOTSTRAP_CLASSPATH_KEY =
"merlin.bootstrap.classpath";
private static final String MERLIN_PROPERTIES_NAME =
@@ -123,11 +125,32 @@
base.mkdirs();
}
+ //
+ // Establish the repository. If a system property corresponding to
+ // MERLIN_REPOSITORY_REMOTE_KEY is not null then setup the repository
+ // so that it dynamcally downloads content. If the value is null then
+ // the repository is restricted to local content (and as such is more
+ // secure).
+ //
+
+ Repository repository = null;
String remote =
- System.getProperty( MERLIN_REPOSITORY_REMOTE_KEY, REPOSITORY );
- URL remoteURL = new URL( remote );
- Repository repository =
- new DefaultFileRepository( base, null, new URL[]{ remoteURL } );
+ System.getProperty( MERLIN_REPOSITORY_REMOTE_KEY );
+ if( remote != null )
+ {
+ URL remoteURL = new URL( remote );
+ repository =
+ new DefaultFileRepository( base, null, new URL[]{ remoteURL } );
+ }
+ else
+ {
+ repository = new DefaultFileRepository( base, null, new URL[0] );
+ }
+
+ //
+ // get the set of URLs for the bootstrap classloader from the
+ // merlin.properties file bundled with the bootstrap jar file
+ //
ClassLoader classloader = Merlin.class.getClassLoader();
InputStream input =
@@ -140,7 +163,7 @@
{
bootstrap = getURLs(
repository,
- properties.getProperty( MERLIN_BOOTSTRAP_CLASSPATH_KEY ) );
+ properties );
}
catch( Throwable e )
{
@@ -152,11 +175,16 @@
return;
}
+ //
+ // create the container bootstrap classloader using these
+ // URLs
+ //
+
ClassLoader loader = new URLClassLoader( bootstrap );
Thread.currentThread().setContextClassLoader( loader );
//
- // get the loader class
+ // get the bootstrap kernel loader class
//
Class clazz;
@@ -178,7 +206,7 @@
}
//
- // instantiate the loader
+ // instantiate the kernel loader
//
try
@@ -201,21 +229,33 @@
}
}
- private static URL[] getURLs( Repository repository, String classpath )
+ private static URL[] getURLs( Repository repository, Properties properties )
{
ArrayList list = new ArrayList();
- StringTokenizer tokenizer = new StringTokenizer( classpath, "," );
- while( tokenizer.hasMoreElements() )
+ final String value = properties.getProperty(
MERLIN_BOOTSTRAP_CLASSPATH_LENGTH_KEY );
+ if( value == null )
{
- final String item = (String)tokenizer.nextElement();
+ throw new NullPointerException( MERLIN_BOOTSTRAP_CLASSPATH_LENGTH_KEY );
+ }
+ int i = Integer.parseInt( value );
+ for( int j=0; j<i; j++ )
+ {
+ final String key = MERLIN_BOOTSTRAP_CLASSPATH_KEY + "." + j;
+ final String item = properties.getProperty( key );
+ if( item == null )
+ {
+ final String error =
+ "Inconsistent bootstrap classpath entry: " + key;
+ throw new IllegalStateException( error );
+ }
try
{
int n = item.indexOf( ":" );
- int m = item.indexOf( ";" );
final String group = item.substring( 0, n );
String artifact = null;
String version = null;
+ int m = item.indexOf( ";" );
if( m > -1 )
{
artifact = item.substring( n+1, m );
@@ -236,6 +276,12 @@
throw new BootstrapRuntimeException( error, e );
}
}
+ //StringTokenizer tokenizer = new StringTokenizer( classpath, "," );
+ //while( tokenizer.hasMoreElements() )
+ //{
+ // final String item = (String)tokenizer.nextElement();
+ //}
+
return (URL[]) list.toArray( new URL[0] );
}
}
1.3 +2 -3
avalon-sandbox/merlin/kernel/impl/src/java/org/apache/avalon/merlin/kernel/impl/CLIKernelLoader.java
Index: CLIKernelLoader.java
===================================================================
RCS file:
/home/cvs/avalon-sandbox/merlin/kernel/impl/src/java/org/apache/avalon/merlin/kernel/impl/CLIKernelLoader.java,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -r1.2 -r1.3
--- CLIKernelLoader.java 12 Aug 2003 05:30:44 -0000 1.2
+++ CLIKernelLoader.java 17 Aug 2003 00:51:57 -0000 1.3
@@ -48,6 +48,8 @@
private static final File HOME = new File( System.getProperty( "user.dir" ) );
+ private static final File SYSTEM = new File( System.getProperty( "merlin.home"
) );
+
private static Resources REZ =
ResourceManager.getPackageResources( CLIKernelLoader.class );
@@ -69,11 +71,8 @@
System.out.println( "\n");
System.out.println( context.toString() );
}
- System.out.println( "## CREATING KERNEL ##");
Kernel kernel = new DefaultKernel( context );
- System.out.println( "## SETTING SHUTDOWN HOOK ##");
setShutdownHook( kernel );
- System.out.println( "## DONE ##");
}
//--------------------------------------------------------------------------
1.3 +1 -2
avalon-sandbox/merlin/kernel/impl/src/java/org/apache/avalon/merlin/kernel/impl/DefaultKernel.java
Index: DefaultKernel.java
===================================================================
RCS file:
/home/cvs/avalon-sandbox/merlin/kernel/impl/src/java/org/apache/avalon/merlin/kernel/impl/DefaultKernel.java,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -r1.2 -r1.3
--- DefaultKernel.java 12 Aug 2003 05:30:44 -0000 1.2
+++ DefaultKernel.java 17 Aug 2003 00:51:57 -0000 1.3
@@ -138,7 +138,6 @@
//
getLogger().info( "context establishment" );
-
ContainmentContext contaiment = null;
try
{
1.4 +127 -4
avalon-sandbox/merlin/kernel/impl/src/java/org/apache/avalon/merlin/kernel/impl/DefaultKernelContext.java
Index: DefaultKernelContext.java
===================================================================
RCS file:
/home/cvs/avalon-sandbox/merlin/kernel/impl/src/java/org/apache/avalon/merlin/kernel/impl/DefaultKernelContext.java,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -r1.3 -r1.4
--- DefaultKernelContext.java 16 Aug 2003 11:19:48 -0000 1.3
+++ DefaultKernelContext.java 17 Aug 2003 00:51:57 -0000 1.4
@@ -57,6 +57,10 @@
import org.apache.avalon.merlin.kernel.KernelContext;
import org.apache.avalon.merlin.kernel.KernelException;
import org.apache.avalon.repository.Repository;
+import org.apache.avalon.repository.ProxyContext;
+import org.apache.avalon.repository.impl.DefaultAuthenticator;
+import org.apache.avalon.repository.impl.DefaultFileRepository;
+import org.apache.avalon.framework.logger.AbstractLogEnabled;
import org.apache.avalon.framework.configuration.Configuration;
import org.apache.avalon.framework.configuration.ConfigurationException;
import org.apache.avalon.framework.configuration.DefaultConfigurationBuilder;
@@ -76,6 +80,7 @@
import org.apache.avalon.composition.model.impl.DefaultSystemContext;
import org.apache.avalon.composition.model.impl.DefaultModelFactory;
import org.apache.excalibur.mpool.PoolManager;
+import org.apache.excalibur.configuration.ConfigurationUtil;
/**
*
@@ -84,7 +89,7 @@
* @see Block
*/
-public class DefaultKernelContext implements KernelContext
+public class DefaultKernelContext extends AbstractLogEnabled implements
KernelContext
{
//==============================================================
// static
@@ -178,8 +183,9 @@
/**
* Creation of a new default kernel context.
* @param repository the bootstrap repository
- * @param system url of a directory against which extension jar
+ * @param system directory against which extension jar
* directives are resolved
+ * @param home local working directory
* @param kernel the kernel configuration URL - if null, the
* default kernel repository will be loaded from the supplied
* repository
@@ -196,7 +202,6 @@
if( repository == null ) throw new NullPointerException( "repository" );
- m_repository = repository;
m_system = system;
m_home = home;
m_kernelURL = kernel;
@@ -232,6 +237,25 @@
Configuration logConfig = m_kernel.getChild( "logging" );
m_logging =
bootstrapLoggingManager( home, logConfig, ROOT_CATEGORY_NAME, debug );
+ enableLogging( m_logging.getSystemLoggerForCategory( "context" ) );
+
+ //
+ // if the kernel configuration declares a repository then we build
+ // a repository based on that defintion otherwise we default to the
+ // bootstrap repository declared under the constructor
+ //
+
+ Configuration repositoryConfig = m_kernel.getChild( "repository", false );
+ if( repositoryConfig == null )
+ {
+ m_repository = repository;
+ getLogger().debug( "using botstrap repository" );
+ }
+ else
+ {
+ m_repository = createRepository( system, repositoryConfig );
+ getLogger().debug( "using custom repository" );
+ }
//
// setup the pool manager
@@ -259,8 +283,107 @@
"Unexpected exception while creating internal model factory.";
throw new KernelException( error, e );
}
+ }
+
+ private Repository createRepository( File root, Configuration config ) throws
KernelException
+ {
+ File base = root;
+ String cache = config.getChild( "cache" ).getValue( null );
+ if( cache != null )
+ {
+ base = new File( cache );
+ getLogger().debug( "setting repository declared cache: " + base );
+ }
+ else
+ {
+ base = new File( root, "repository" );
+ getLogger().debug( "setting repository to: " + base );
+ }
+
+ if( !base.exists() ) base.mkdirs();
+
+ //
+ // set the remote repository urls
+ //
+
+ final Configuration[] hosts = config.getChild( "hosts" ).getChildren(
"host" );
+ final URL[] list = new URL[ hosts.length ];
+ for( int i=0; i<hosts.length; i++ )
+ {
+ Configuration host = hosts[i];
+ try
+ {
+ String path = host.getValue();
+ if( !path.endsWith( "/" ) )
+ {
+ path = path + "/";
+ }
+ URL url = new URL( path );
+ final String protocol = url.getProtocol();
+ if( url.getProtocol().equals( "http" ) )
+ {
+ list[i] = url;
+ }
+ else
+ {
+ final String error =
+ "Unsupported protocol: " + protocol;
+ throw new KernelException( error );
+ }
+ }
+ catch( Throwable e )
+ {
+ final String error =
+ "Invalid host declaration: "
+ + ConfigurationUtil.list( host );
+ throw new KernelException( error, e );
+ }
+ }
+ //
+ // handle the proxy declaration
+ //
+
+ ProxyContext proxy = null;
+ Configuration proxyConfig = config.getChild( "proxy", false );
+ if( proxyConfig != null )
+ {
+ Configuration credentials = proxyConfig.getChild( "credentials" );
+ final String username = credentials.getChild( "username" ).getValue(
null );
+ if( username == null )
+ {
+ final String error =
+ "Credentials configuration does not contain the required
'username' element."
+ + ConfigurationUtil.list( credentials );
+ throw new KernelException( error );
+ }
+
+ final String password = credentials.getChild( "password" ).getValue(
null );
+ if( password == null )
+ {
+ final String error =
+ "Credentials configuration does not contain the required
'password' element."
+ + ConfigurationUtil.list( credentials );
+ throw new KernelException( error );
+ }
+
+ DefaultAuthenticator authenticator =
+ new DefaultAuthenticator( username, password );
+
+ final String host = proxyConfig.getChild( "host" ).getValue( null );
+ final int port = proxyConfig.getChild( "port" ).getValueAsInteger( 0 );
+ if( host == null )
+ {
+ final String error =
+ "Proxy configuration does not contain the required 'host'
element."
+ + ConfigurationUtil.list( proxyConfig );
+ throw new KernelException( error );
+ }
+ getLogger().debug( "repository proxy: " + host + ":" + port );
+ proxy = new ProxyContext( host, port, authenticator );
+ }
+ return new DefaultFileRepository( base, proxy, list );
}
//--------------------------------------------------------------
1.4 +7 -5 avalon-sandbox/merlin/merlin-platform/src/config/wrapper.conf
Index: wrapper.conf
===================================================================
RCS file: /home/cvs/avalon-sandbox/merlin/merlin-platform/src/config/wrapper.conf,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -r1.3 -r1.4
--- wrapper.conf 12 Aug 2003 05:30:44 -0000 1.3
+++ wrapper.conf 17 Aug 2003 00:51:57 -0000 1.4
@@ -27,12 +27,14 @@
# Application parameters. Add parameters as needed starting from 1
wrapper.app.parameter.1=Merlin
wrapper.app.parameter.2=-server
+wrapper.app.parameter.3=-system
+wrapper.app.parameter.4=./..
wrapper.app.parameter.3=-kernel
-wrapper.app.parameter.4=../config/kernel.xml
+wrapper.app.parameter.4=./../config/kernel.xml
wrapper.app.parameter.5=-home
-wrapper.app.parameter.6=../
+wrapper.app.parameter.6=./..
wrapper.app.parameter.7=-config
-wrapper.app.parameter.8=../config/config.xml
+wrapper.app.parameter.8=./../config/config.xml
# Port which the native wrapper code will attempt to connect to
wrapper.port=1777
@@ -59,11 +61,11 @@
# the log is rolled. Size is specified in bytes. The default value
# of 0, disables log rolling. May abbreviate with the 'k' (kb) or
# 'm' (mb) suffix. For example: 10m = 10 megabytes.
-wrapper.logfile.maxsize=0
+wrapper.logfile.maxsize=10m
# Maximum number of rolled log files which will be allowed before old
# files are deleted. The default value of 0 implies no limit.
-wrapper.logfile.maxfiles=0
+wrapper.logfile.maxfiles=10
# Log Level for sys/event log output. (See docs for log levels)
wrapper.syslog.loglevel=NONE
1.2 +4 -3
avalon-sandbox/merlin/repository/impl/src/java/org/apache/avalon/repository/impl/DefaultFileRepository.java
Index: DefaultFileRepository.java
===================================================================
RCS file:
/home/cvs/avalon-sandbox/merlin/repository/impl/src/java/org/apache/avalon/repository/impl/DefaultFileRepository.java,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- DefaultFileRepository.java 11 Aug 2003 22:37:15 -0000 1.1
+++ DefaultFileRepository.java 17 Aug 2003 00:51:57 -0000 1.2
@@ -274,7 +274,8 @@
if( !application.exists() )
{
final String error =
- "Unknown group: " + group;
+ "Unknown group: '" + group
+ + "' relative to the repository base: '" + m_base + "'.";
throw new RepositoryException( error );
}
@@ -284,7 +285,7 @@
final String error =
"No resources of the type: '" + type
+ "' in the group: '" + group
- + ". File: '" + types + "'.";
+ + "'. File: '" + types + "'.";
throw new RepositoryException( error );
}
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]