001/* 002 * (C) Copyright 2006-2011 Nuxeo SA (http://nuxeo.com/) and others. 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 * 016 * Contributors: 017 * Nuxeo - initial API and implementation 018 * 019 * $Id$ 020 */ 021 022package org.nuxeo.osgi.application; 023 024import java.io.File; 025import java.io.IOException; 026import java.lang.reflect.InvocationTargetException; 027import java.lang.reflect.Method; 028import java.net.MalformedURLException; 029import java.net.URL; 030import java.net.URLClassLoader; 031import java.util.ArrayList; 032import java.util.List; 033 034/** 035 * @author <a href="mailto:bs@nuxeo.com">Bogdan Stefanescu</a> 036 */ 037public class Main { 038 039 public static void main(String[] args) throws Exception { 040 if (args.length == 0) { 041 System.err.println("No classpath specified"); 042 System.exit(10); 043 } 044 ClassLoader cl = Thread.currentThread().getContextClassLoader(); 045 if (!(cl instanceof URLClassLoader)) { 046 System.err.println("Not a valid class loader: " + cl); 047 System.exit(10); 048 } 049 ClassLoader parent = cl.getParent(); 050 if (parent == null) { 051 parent = ClassLoader.getSystemClassLoader(); 052 } 053 RootClassLoader rootLoader = new RootClassLoader(parent, SharedClassLoader.class); 054 SharedClassLoaderImpl classLoader = new SharedClassLoaderImpl(((URLClassLoader) cl).getURLs(), rootLoader); 055 Thread.currentThread().setContextClassLoader(classLoader.getLoader()); 056 URL systemBundle = classLoader.getURLs()[0]; 057 // build the class path now 058 List<File> cp = buildClassPath(classLoader, args[0]); 059 // make new arguments by removing the first one to pass further 060 String[] tmp = new String[args.length - 1]; 061 System.arraycopy(args, 1, tmp, 0, tmp.length); 062 args = tmp; 063 // reload classes from this JAR using a SharedClassLoader 064 Class<?> me = classLoader.loadClass(StandaloneApplication.class.getName()); 065 Method main = me.getMethod("main", URL.class, List.class, String[].class); 066 main.invoke(null, systemBundle, cp, args); 067 } 068 069 public static List<File> buildClassPath(SharedClassLoader classLoader, String rawcp) throws IOException { 070 List<File> result = new ArrayList<File>(); 071 String[] cp = rawcp.split(":"); 072 for (String entry : cp) { 073 File entryFile; 074 if (entry.endsWith("/.")) { 075 entryFile = new File(entry.substring(0, entry.length() - 2)); 076 File[] files = entryFile.listFiles(); 077 if (files != null) { 078 for (File file : files) { 079 result.add(file); 080 classLoader.addURL(file.toURI().toURL()); 081 } 082 } 083 } else { 084 entryFile = new File(entry); 085 result.add(entryFile); 086 classLoader.addURL(entryFile.toURI().toURL()); 087 } 088 } 089 return result; 090 } 091 092 private static class RootClassLoader extends ClassLoader { 093 094 private final Class<?> loaderClass; 095 096 private final String loaderName; 097 098 RootClassLoader(ClassLoader parent, Class<?> loaderClass) { 099 super(parent); 100 this.loaderClass = loaderClass; 101 loaderName = loaderClass.getName(); 102 } 103 104 @Override 105 protected Class<?> findClass(String name) throws ClassNotFoundException { 106 if (loaderName.equals(name)) { 107 return loaderClass; 108 } 109 throw new ClassNotFoundException(name); 110 } 111 112 } 113 114}