2
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
4
* Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
6
* The contents of this file are subject to the terms of either the GNU
7
* General Public License Version 2 only ("GPL") or the Common
8
* Development and Distribution License("CDDL") (collectively, the
9
* "License"). You may not use this file except in compliance with the
10
* License. You can obtain a copy of the License at
11
* http://www.netbeans.org/cddl-gplv2.html
12
* or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
13
* specific language governing permissions and limitations under the
14
* License. When distributing the software, include this License Header
15
* Notice in each file and include the License file at
16
* nbbuild/licenses/CDDL-GPL-2-CP. Sun designates this
17
* particular file as subject to the "Classpath" exception as provided
18
* by Sun in the GPL Version 2 section of the License file that
19
* accompanied this code. If applicable, add the following below the
20
* License Header, with the fields enclosed by brackets [] replaced by
21
* your own identifying information:
22
* "Portions Copyrighted [year] [name of copyright owner]"
26
* The Original Software is NetBeans. The Initial Developer of the Original
27
* Software is Sun Microsystems, Inc. Portions Copyright 1997-2007 Sun
28
* Microsystems, Inc. All Rights Reserved.
30
* If you wish your version of this file to be governed by only the CDDL
31
* or only the GPL Version 2, indicate your decision by adding
32
* "[Contributor] elects to include this software in this distribution
33
* under the [CDDL or GPL Version 2] license." If you do not indicate a
34
* single choice of license, a recipient has the option to distribute
35
* your version of this file under either the CDDL, the GPL Version 2 or
36
* to extend the choice of license to its licensees as provided above.
37
* However, if you add GPL Version 2 code and therefore, elected the GPL
38
* Version 2 license, then the option applies only if the new code is
39
* made subject to such option by the copyright holder.
45
import java.io.IOException;
46
import java.io.InputStream;
47
import java.lang.reflect.Method;
49
import java.net.URLConnection;
50
import java.security.AllPermission;
51
import java.security.CodeSource;
52
import java.security.PermissionCollection;
53
import java.security.Permissions;
54
import java.util.ArrayList;
55
import java.util.Collection;
56
import java.util.Enumeration;
57
import java.util.HashSet;
58
import java.util.List;
60
import java.util.StringTokenizer;
61
import org.openide.util.Lookup;
62
import org.openide.util.lookup.Lookups;
64
/** Bootstrap main class.
65
* @author Jaroslav Tulach, Jesse Glick
67
final class MainImpl extends Object {
70
* @param args the command line arguments
71
* @throws Exception for lots of reasons
73
public static void main (String args[]) throws Exception {
74
java.lang.reflect.Method[] m = new java.lang.reflect.Method[1];
75
int res = execute (args, System.in, System.out, System.err, m);
77
// Connected to another running NB instance and succeeded in making a call.
79
} else if (res != 0) {
80
// Some CLIHandler refused the invocation
84
m[0].invoke (null, new Object[] { args });
87
/** Returns string describing usage of the system. Does that by talking to
88
* all registered handlers and asking them to show their usage.
90
* @return the usage string for the system
92
public static String usage () throws Exception {
93
java.io.ByteArrayOutputStream os = new java.io.ByteArrayOutputStream ();
94
java.io.ByteArrayOutputStream err = new java.io.ByteArrayOutputStream ();
96
String[] newArgs = { "--help" };
98
execute(newArgs, System.in, os, err, null);
99
return new String (os.toByteArray ());
102
/** Constructs the correct ClassLoader, finds main method to execute
103
* and invokes all registered CLIHandlers.
105
* @param args the arguments to pass to the handlers
106
* @param reader the input stream reader for the handlers
107
* @param writer the output stream for the handlers
108
* @param methodToCall null or array with one item that will be set to
109
* a method that shall be executed as the main application
113
java.io.InputStream reader,
114
java.io.OutputStream writer,
115
java.io.OutputStream error,
116
java.lang.reflect.Method[] methodToCall
118
// #42431: turn off jar: caches, they are evil
119
// Note that setDefaultUseCaches changes a static field
120
// yet for some reason it is an instance method!
121
new URLConnection(MainImpl.class.getResource("Main.class")) { // NOI18N
122
public void connect() throws IOException {}
123
}.setDefaultUseCaches(false);
125
ArrayList<File> list = new ArrayList<File>();
127
HashSet<File> processedDirs = new HashSet<File> ();
128
String home = System.getProperty ("netbeans.home"); // NOI18N
130
build_cp (new File (home), list, processedDirs);
132
// #34069: need to do the same for nbdirs.
133
String nbdirs = System.getProperty("netbeans.dirs"); // NOI18N
134
if (nbdirs != null) {
135
StringTokenizer tok = new StringTokenizer(nbdirs, File.pathSeparator);
136
while (tok.hasMoreTokens()) {
137
// passing false as last argument as we need to initialize openfile-cli.jar
138
build_cp(new File(tok.nextToken()), list, processedDirs);
145
String prepend = System.getProperty("netbeans.classpath"); // NOI18N
146
if (prepend != null) {
147
StringTokenizer tok = new StringTokenizer (prepend, File.pathSeparator);
148
while (tok.hasMoreElements()) {
149
File f = new File(tok.nextToken());
154
// Compute effective dynamic classpath (mostly lib/*.jar) for TopLogging, NbInstaller:
155
StringBuffer buf = new StringBuffer(1000);
156
for (File o : list) {
157
String f = o.getAbsolutePath();
158
if (buf.length() > 0) {
159
buf.append(File.pathSeparatorChar);
163
System.setProperty("netbeans.dynamic.classpath", buf.toString());
165
BootClassLoader loader = new BootClassLoader(list, new ClassLoader[] {
166
MainImpl.class.getClassLoader()
169
// Needed for Lookup.getDefault to find NbTopManager.Lkp.
170
// Note that ModuleManager.updateContextClassLoaders will later change
171
// the loader on this and other threads to be MM.SystemClassLoader anyway.
172
Thread.currentThread().setContextClassLoader (loader);
176
// Evaluate command line interfaces and lock the user directory
179
CLIHandler.Status result;
180
result = CLIHandler.initialize(args, reader, writer, error, loader, true, false, loader);
181
if (result.getExitCode () == CLIHandler.Status.CANNOT_CONNECT) {
182
int value = javax.swing.JOptionPane.showConfirmDialog (
184
java.util.ResourceBundle.getBundle("org/netbeans/Bundle").getString("MSG_AlreadyRunning"),
185
java.util.ResourceBundle.getBundle("org/netbeans/Bundle").getString("MSG_AlreadyRunningTitle"),
186
javax.swing.JOptionPane.OK_CANCEL_OPTION,
187
javax.swing.JOptionPane.WARNING_MESSAGE
189
if (value == javax.swing.JOptionPane.OK_OPTION) {
190
result = CLIHandler.initialize(args, reader, writer, error, loader, true, true, loader);
195
String className = System.getProperty(
196
"netbeans.mainclass", "org.netbeans.core.startup.Main" // NOI18N
199
Class<?> c = loader.loadClass(className);
200
Method m = c.getMethod ("main", String[].class); // NOI18N
202
if (methodToCall != null) {
206
return result.getExitCode ();
210
* Call when the system is up and running, to complete handling of
211
* delayed command-line options like -open FILE.
213
public static void finishInitialization() {
214
int r = CLIHandler.finishInitialization (false);
216
// Not much to do about it.
217
System.err.println ("Post-initialization command-line options could not be run."); // NOI18N
218
//System.err.println("r=" + r + " args=" + java.util.Arrays.asList(args.getArguments()));
222
static final class BootClassLoader extends JarClassLoader
223
implements Runnable {
224
private Lookup metaInf;
226
private List<CLIHandler> handlers;
228
public BootClassLoader(List<File> cp, ClassLoader[] parents) {
231
metaInf = Lookups.metaInfServices(this);
236
value = searchBuildNumber(this.getResources("META-INF/MANIFEST.MF"));
238
value = searchBuildNumber(this.simpleFindResources("META-INF/MANIFEST.MF"));
240
} catch (IOException ex) {
241
ex.printStackTrace();
245
System.err.println("Cannot set netbeans.buildnumber property no OpenIDE-Module-Implementation-Version found"); // NOI18N
247
System.setProperty ("netbeans.buildnumber", value); // NOI18N
251
/** @param en enumeration of URLs */
252
private static String searchBuildNumber(Enumeration<URL> en) {
255
java.util.jar.Manifest mf;
257
while(en.hasMoreElements()) {
258
u = en.nextElement();
259
InputStream is = u.openStream();
260
mf = new java.util.jar.Manifest(is);
262
value = mf.getMainAttributes().getValue("OpenIDE-Module-Implementation-Version"); // NOI18N
267
} catch (IOException ex) {
268
ex.printStackTrace();
273
private boolean onlyRunRunOnce;
274
/** Checks for new JARs in netbeans.user */
276
// do not call this method twice
277
if (onlyRunRunOnce) return;
278
onlyRunRunOnce = true;
280
ArrayList<File> toAdd = new ArrayList<File> ();
281
String user = System.getProperty ("netbeans.user"); // NOI18N
284
build_cp (new File (user), toAdd, new HashSet<File> ());
287
if (!toAdd.isEmpty ()) {
289
metaInf = Lookups.metaInfServices(this);
290
if (handlers != null) {
292
handlers.addAll(metaInf.lookupAll(CLIHandler.class));
295
} catch (IOException ex) {
296
ex.printStackTrace();
301
/** Startup optimalization. See issue 27226. */
302
protected PermissionCollection getPermissions(CodeSource cs) {
303
return getAllPermission();
305
/** Startup optimalization. See issue 27226. */
306
private static PermissionCollection modulePermissions;
307
/** Startup optimalization. See issue 27226. */
308
private static synchronized PermissionCollection getAllPermission() {
309
if (modulePermissions == null) {
310
modulePermissions = new Permissions();
311
modulePermissions.add(new AllPermission());
312
modulePermissions.setReadOnly();
314
return modulePermissions;
317
/** For a given classloader finds all registered CLIHandlers.
319
public final Collection allCLIs () {
320
if (handlers == null) {
321
handlers = new ArrayList<CLIHandler>(metaInf.lookupAll(CLIHandler.class));
325
} // end of BootClassLoader
327
private static void append_jars_to_cp (File dir, Collection<File> toAdd) throws IOException {
328
if (!dir.isDirectory()) return;
330
File[] arr = dir.listFiles();
331
for (int i = 0; i < arr.length; i++) {
332
String n = arr[i].getName ();
334
if (n.equals("updater.jar") || // NOI18N
335
(dir.getName().equals("locale") && n.startsWith("updater_") && n.endsWith(".jar"))) { // NOI18N
336
// Used by launcher, not by us.
340
if (n.endsWith("jar") || n.endsWith ("zip")) { // NOI18N
347
private static void build_cp(File base, Collection<File> toAdd, Set<File> processedDirs)
348
throws java.io.IOException {
349
if (!processedDirs.add (base)) {
354
append_jars_to_cp(new File(base, "core/patches"), toAdd); // NOI18N
355
append_jars_to_cp(new File(base, "core"), toAdd); // NOI18N
356
// XXX a minor optimization: exclude any unused locale JARs
357
// For example, lib/locale/ might contain:
362
// core_f4j_ce_ja.jar
366
// Only some of these will apply to the current session, based on the
367
// current values of Locale.default and NbBundle.branding.
368
append_jars_to_cp(new File(base, "core/locale"), toAdd); // NOI18N