001: /**
002: * Licensed to the Apache Software Foundation (ASF) under one or more
003: * contributor license agreements. See the NOTICE file distributed with
004: * this work for additional information regarding copyright ownership.
005: * The ASF licenses this file to You under the Apache License, Version 2.0
006: * (the "License"); you may not use this file except in compliance with
007: * the License. You may obtain a copy of the License at
008: *
009: * http://www.apache.org/licenses/LICENSE-2.0
010: *
011: * Unless required by applicable law or agreed to in writing, software
012: * distributed under the License is distributed on an "AS IS" BASIS,
013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014: * See the License for the specific language governing permissions and
015: * limitations under the License.
016: */package org.apache.openejb.client;
017:
018: import javax.naming.InitialContext;
019: import javax.naming.NameNotFoundException;
020: import javax.security.auth.Subject;
021: import javax.security.auth.callback.CallbackHandler;
022: import javax.security.auth.login.LoginContext;
023: import java.io.File;
024: import java.lang.reflect.Field;
025: import java.lang.reflect.Method;
026: import java.lang.reflect.InvocationTargetException;
027: import java.net.URL;
028: import java.net.URLClassLoader;
029: import java.net.URLDecoder;
030: import java.security.AccessController;
031: import java.security.PrivilegedAction;
032: import java.security.PrivilegedExceptionAction;
033: import java.util.ArrayList;
034: import java.util.List;
035:
036: /**
037: * @version $Rev: 634198 $ $Date: 2008-03-06 01:23:13 -0800 $
038: */
039: public class Main {
040: public static void main(String[] args) throws Exception {
041: args = siftArgs(args);
042:
043: System.setProperty(javax.naming.Context.URL_PKG_PREFIXES,
044: "org.apache.openejb.client");
045:
046: // the new initial context is automatically hooked up to the server side
047: // java:openejb/client/${clientModuleId} tree
048: InitialContext initialContext = new InitialContext();
049:
050: // path to the client jar file
051: String path = (String) initialContext.lookup("java:comp/path");
052: // TODO: Download the file
053: File file = new File(path);
054:
055: // Create a child class loader containing the application jar
056: ClassLoader classLoader = Thread.currentThread()
057: .getContextClassLoader();
058: if (classLoader == null) {
059: classLoader = new URLClassLoader(new URL[] { file.toURL() });
060: } else {
061: classLoader = new URLClassLoader(
062: new URL[] { file.toURL() }, classLoader);
063: }
064: Thread.currentThread().setContextClassLoader(classLoader);
065:
066: // load the main class and get the main method
067: // do this first so we fail fast on a bad class path
068: String mainClassName = (String) initialContext
069: .lookup("java:comp/mainClass");
070: Class mainClass = classLoader.loadClass(mainClassName);
071: final Method mainMethod = mainClass.getMethod("main",
072: String[].class);
073:
074: // load the callback handler class
075: // again do this before any major work so we can fail fase
076: Class callbackHandlerClass = null;
077: try {
078: String callbackHandlerName = (String) initialContext
079: .lookup("java:comp/callbackHandler");
080: callbackHandlerClass = classLoader
081: .loadClass(callbackHandlerName);
082: } catch (NameNotFoundException ignored) {
083: }
084:
085: InjectionMetaData injectionMetaData = (InjectionMetaData) initialContext
086: .lookup("java:comp/injections");
087: ClientInstance.get().setComponent(InjectionMetaData.class,
088: injectionMetaData);
089: for (Injection injection : injectionMetaData.getInjections()) {
090: try {
091: Object value = initialContext.lookup("java:comp/env/"
092: + injection.getJndiName());
093: Class target = classLoader.loadClass(injection
094: .getTargetClass());
095: Field field = target.getDeclaredField(injection
096: .getName());
097: setAccessible(field);
098: field.set(null, value);
099: } catch (Throwable e) {
100: System.err.println("Injection FAILED: class="
101: + injection.getTargetClass() + ", name="
102: + injection.getName() + ", jndi-ref="
103: + injection.getJndiName());
104: e.printStackTrace();
105: }
106: }
107:
108: // if there is no security then just call the main method
109: final Object[] mainArgs = new Object[] { args };
110: if (callbackHandlerClass == null) {
111: invoke(mainMethod, mainArgs);
112: } else {
113: // create the callback handler
114: CallbackHandler callbackHandler = (CallbackHandler) callbackHandlerClass
115: .newInstance();
116:
117: // initialize the jaas system
118: loadJassLoginConfig(classLoader);
119:
120: // login
121: LoginContext loginContext = new LoginContext("ClientLogin",
122: callbackHandler);
123: loginContext.login();
124:
125: // success - get the subject
126: Subject subject = loginContext.getSubject();
127:
128: // call the main method in a doAs so the subject is associated with the thread
129: try {
130: Subject.doAs(subject, new PrivilegedExceptionAction() {
131: public Object run() throws Exception {
132: invoke(mainMethod, mainArgs);
133: return null;
134: }
135: });
136: } finally {
137: // And finally, logout
138: loginContext.logout();
139: }
140: }
141: }
142:
143: private static void invoke(Method mainMethod, Object[] mainArgs)
144: throws Exception {
145: try {
146: mainMethod.invoke(null, mainArgs);
147: } catch (InvocationTargetException e) {
148: Throwable cause = e.getCause();
149: if (cause instanceof Exception) {
150: throw (Exception) cause;
151: } else if (cause instanceof Error) {
152: throw (Error) cause;
153: }
154: throw new Error(e);
155: }
156: }
157:
158: private static void loadJassLoginConfig(ClassLoader classLoader) {
159: String path = System
160: .getProperty("java.security.auth.login.config");
161: if (path == null) {
162: URL resource = classLoader.getResource("client.login.conf");
163: if (resource != null) {
164: System.setProperty("java.security.auth.login.config",
165: URLDecoder.decode(resource.toExternalForm()));
166: }
167: }
168: }
169:
170: private static String[] siftArgs(String[] args) {
171: List<String> argsList = new ArrayList<String>();
172: for (int i = 0; i < args.length; i++) {
173: String arg = args[i];
174: if (arg.indexOf("-D") == -1) {
175: argsList.add(arg);
176: } else {
177: String prop = arg.substring(arg.indexOf("-D") + 2, arg
178: .indexOf("="));
179: String val = arg.substring(arg.indexOf("=") + 1);
180: System.setProperty(prop, val);
181: }
182: }
183: return argsList.toArray(new String[argsList.size()]);
184: }
185:
186: private static void setAccessible(final Field field) {
187: AccessController.doPrivileged(new PrivilegedAction<Object>() {
188: public Object run() {
189: field.setAccessible(true);
190: return null;
191: }
192: });
193: }
194: }
|