2
Copyright (C) 2002-2011 Jeroen Frijters
4
This software is provided 'as-is', without any express or implied
5
warranty. In no event will the authors be held liable for any damages
6
arising from the use of this software.
8
Permission is granted to anyone to use this software for any purpose,
9
including commercial applications, and to alter it and redistribute it
10
freely, subject to the following restrictions:
12
1. The origin of this software must not be misrepresented; you must not
13
claim that you wrote the original software. If you use this software
14
in a product, an acknowledgment in the product documentation would be
15
appreciated but is not required.
16
2. Altered source versions must be plainly marked as such, and must not be
17
misrepresented as being the original software.
18
3. This notice may not be removed or altered from any source distribution.
26
using System.Reflection;
30
using java.lang.reflect;
35
using Console = System.Console;
36
using System.Diagnostics;
42
private static Timer t;
43
private DateTime now = DateTime.Now;
52
Console.WriteLine(DateTime.Now - now);
56
private class SaveAssemblyShutdownHook : java.lang.Thread
58
private java.lang.Class clazz;
60
internal SaveAssemblyShutdownHook(java.lang.Class clazz)
61
: base("SaveAssemblyShutdownHook")
66
public override void run()
68
System.Threading.Thread.CurrentThread.Priority = System.Threading.ThreadPriority.AboveNormal;
69
Console.Error.WriteLine("Saving dynamic assembly...");
72
IKVM.Internal.Starter.SaveDebugImage();
73
Console.Error.WriteLine("Saving done.");
77
Console.Error.WriteLine(x);
78
Console.Error.WriteLine(new System.Diagnostics.StackTrace(x, true));
79
System.Diagnostics.Debug.Assert(false, x.ToString());
84
private class WaitShutdownHook : java.lang.Thread
86
internal WaitShutdownHook()
87
: base("WaitShutdownHook")
91
public override void run()
93
Console.Error.WriteLine("IKVM runtime terminated. Waiting for Ctrl+C...");
96
System.Threading.Thread.Sleep(System.Threading.Timeout.Infinite);
101
[STAThread] // NOTE this is here because otherwise SWT's RegisterDragDrop (a COM thing) doesn't work
102
[IKVM.Attributes.HideFromJava]
103
static int Main(string[] args)
105
Tracer.EnableTraceConsoleListener();
106
Tracer.EnableTraceForDebug();
107
System.Collections.Hashtable props = new System.Collections.Hashtable();
108
string classpath = Environment.GetEnvironmentVariable("CLASSPATH");
109
if(classpath == null || classpath == "")
113
props["java.class.path"] = classpath;
115
bool saveAssembly = false;
116
bool saveAssemblyX = false;
117
bool waitOnExit = false;
118
bool showVersion = false;
119
string mainClass = null;
120
int vmargsIndex = -1;
122
String debugArg = null;
123
bool noglobbing = false;
124
for(int i = 0; i < args.Length; i++)
126
String arg = args[i];
129
if(arg == "-help" || arg == "-?")
133
else if(arg == "-Xsave")
136
IKVM.Internal.Starter.PrepareForSaveDebugImage();
138
else if(arg == "-XXsave")
140
saveAssemblyX = true;
141
IKVM.Internal.Starter.PrepareForSaveDebugImage();
143
else if(arg == "-Xtime")
147
else if(arg == "-Xwait")
151
else if(arg == "-Xbreak")
153
System.Diagnostics.Debugger.Break();
155
else if(arg == "-Xnoclassgc")
157
IKVM.Internal.Starter.ClassUnloading = false;
159
else if(arg == "-Xverify")
161
IKVM.Internal.Starter.RelaxedVerification = false;
163
else if(arg == "-jar")
167
else if(arg == "-version")
169
Console.WriteLine(Startup.getVersionAndCopyrightInfo());
171
Console.WriteLine("CLR version: {0} ({1} bit)", Environment.Version, IntPtr.Size * 8);
172
System.Type type = System.Type.GetType("Mono.Runtime");
175
Console.WriteLine("Mono version: {0}", type.InvokeMember("GetDisplayName", BindingFlags.InvokeMethod | BindingFlags.Static | BindingFlags.NonPublic, null, null, new object[0]));
177
foreach(Assembly asm in AppDomain.CurrentDomain.GetAssemblies())
179
Console.WriteLine("{0}: {1}", asm.GetName().Name, asm.GetName().Version);
181
string ver = java.lang.System.getProperty("openjdk.version");
184
Console.WriteLine("OpenJDK version: {0}", ver);
188
else if(arg == "-showversion")
192
else if(arg.StartsWith("-D"))
194
arg = arg.Substring(2);
195
string[] keyvalue = arg.Split('=');
197
if(keyvalue.Length == 2) // -Dabc=x
201
else if (keyvalue.Length == 1) // -Dabc
207
value = arg.Substring(keyvalue[0].Length + 1);
209
props[keyvalue[0]] = value;
211
else if(arg == "-ea" || arg == "-enableassertions")
213
IKVM.Runtime.Assertions.EnableAssertions();
215
else if(arg == "-da" || arg == "-disableassertions")
217
IKVM.Runtime.Assertions.DisableAssertions();
219
else if(arg == "-esa" || arg == "-enablesystemassertions")
221
IKVM.Runtime.Assertions.EnableSystemAssertions();
223
else if(arg == "-dsa" || arg == "-disablesystemassertions")
225
IKVM.Runtime.Assertions.DisableSystemAssertions();
227
else if(arg.StartsWith("-ea:") || arg.StartsWith("-enableassertions:"))
229
IKVM.Runtime.Assertions.EnableAssertions(arg.Substring(arg.IndexOf(':') + 1));
231
else if(arg.StartsWith("-da:") || arg.StartsWith("-disableassertions:"))
233
IKVM.Runtime.Assertions.DisableAssertions(arg.Substring(arg.IndexOf(':') + 1));
235
else if(arg == "-cp" || arg == "-classpath")
237
props["java.class.path"] = args[++i];
239
else if(arg.StartsWith("-Xtrace:"))
241
Tracer.SetTraceLevel(arg.Substring(8));
243
else if(arg.StartsWith("-Xmethodtrace:"))
245
Tracer.HandleMethodTrace(arg.Substring(14));
247
else if(arg == "-Xdebug")
251
else if (arg == "-Xnoagent")
253
//ignore it, disable support for oldjdb
255
else if (arg.StartsWith("-Xrunjdwp") || arg.StartsWith("-agentlib:jdwp"))
260
else if (arg.StartsWith("-Xreference:"))
262
Startup.addBootClassPathAssemby(Assembly.LoadFrom(arg.Substring(12)));
264
else if (arg == "-Xnoglobbing")
268
else if (arg.StartsWith("-Xms")
269
|| arg.StartsWith("-Xmx")
270
|| arg.StartsWith("-Xss")
277
|| arg == "-Xcheck:jni"
278
|| arg == "-Xshare:off"
279
|| arg == "-Xshare:auto"
280
|| arg == "-Xshare:on"
283
Console.Error.WriteLine("Unsupported option ignored: {0}", arg);
287
Console.Error.WriteLine("{0}: illegal argument", arg);
298
if(mainClass == null || showVersion)
300
Console.Error.WriteLine(Startup.getVersionAndCopyrightInfo());
301
Console.Error.WriteLine();
303
if(mainClass == null)
305
Console.Error.WriteLine("usage: ikvm [-options] <class> [args...]");
306
Console.Error.WriteLine(" (to execute a class)");
307
Console.Error.WriteLine(" or ikvm -jar [-options] <jarfile> [args...]");
308
Console.Error.WriteLine(" (to execute a jar file)");
309
Console.Error.WriteLine();
310
Console.Error.WriteLine("where options include:");
311
Console.Error.WriteLine(" -? -help Display this message");
312
Console.Error.WriteLine(" -version Display IKVM and runtime version");
313
Console.Error.WriteLine(" -showversion Display version and continue running");
314
Console.Error.WriteLine(" -cp -classpath <directories and zip/jar files separated by {0}>", Path.PathSeparator);
315
Console.Error.WriteLine(" Set search path for application classes and resources");
316
Console.Error.WriteLine(" -D<name>=<value> Set a system property");
317
Console.Error.WriteLine(" -ea[:<packagename>...|:<classname>]");
318
Console.Error.WriteLine(" -enableassertions[:<packagename>...|:<classname>]");
319
Console.Error.WriteLine(" Enable assertions.");
320
Console.Error.WriteLine(" -da[:<packagename>...|:<classname>]");
321
Console.Error.WriteLine(" -disableassertions[:<packagename>...|:<classname>]");
322
Console.Error.WriteLine(" Disable assertions");
323
Console.Error.WriteLine(" -Xsave Save the generated assembly (for debugging)");
324
Console.Error.WriteLine(" -Xtime Time the execution");
325
Console.Error.WriteLine(" -Xtrace:<string> Displays all tracepoints with the given name");
326
Console.Error.WriteLine(" -Xmethodtrace:<string>");
327
Console.Error.WriteLine(" Builds method trace into the specified output methods");
328
Console.Error.WriteLine(" -Xwait Keep process hanging around after exit");
329
Console.Error.WriteLine(" -Xbreak Trigger a user defined breakpoint at startup");
330
Console.Error.WriteLine(" -Xnoclassgc Disable class garbage collection");
331
Console.Error.WriteLine(" -Xnoglobbing Disable argument globbing");
332
Console.Error.WriteLine(" -Xverify Enable strict class file verification");
339
// Starting the debugger
340
Assembly asm = Assembly.GetExecutingAssembly();
341
String arguments = debugArg + " -pid:" + System.Diagnostics.Process.GetCurrentProcess().Id;
342
String program = new FileInfo(asm.Location).DirectoryName + "\\debugger.exe";
345
ProcessStartInfo info = new ProcessStartInfo(program, arguments);
346
info.UseShellExecute = false;
347
Process debugger = new Process();
348
debugger.StartInfo = info;
353
Console.Error.WriteLine(program + " " + arguments);
359
props["java.class.path"] = mainClass;
361
// like the JDK we don't quote the args (even if they contain spaces)
362
props["sun.java.command"] = String.Join(" ", args, vmargsIndex - 1, args.Length - (vmargsIndex - 1));
363
props["sun.java.launcher"] = "SUN_STANDARD";
364
Startup.setProperties(props);
365
Startup.enterMainThread();
369
vmargs = new string[args.Length - vmargsIndex];
370
System.Array.Copy(args, vmargsIndex, vmargs, 0, vmargs.Length);
374
// Startup.glob() uses Java code, so we need to do this after we've initialized
375
vmargs = Startup.glob(args, vmargsIndex);
379
mainClass = GetMainClassFromJarManifest(mainClass);
380
if (mainClass == null)
385
java.lang.Class clazz = java.lang.Class.forName(mainClass, true, java.lang.ClassLoader.getSystemClassLoader());
388
Method method = IKVM.Internal.Starter.FindMainMethod(clazz);
391
throw new java.lang.NoSuchMethodError("main");
393
else if(!Modifier.isPublic(method.getModifiers()))
395
Console.Error.WriteLine("Main method not public.");
399
// if clazz isn't public, we can still call main
400
method.setAccessible(true);
403
java.lang.Runtime.getRuntime().addShutdownHook(new SaveAssemblyShutdownHook(clazz));
407
java.lang.Runtime.getRuntime().addShutdownHook(new WaitShutdownHook());
411
method.invoke(null, new object[] { vmargs });
414
catch(InvocationTargetException x)
424
IKVM.Internal.Starter.SaveDebugImage();
428
catch(System.Exception x)
430
java.lang.Thread thread = java.lang.Thread.currentThread();
431
thread.getThreadGroup().uncaughtException(thread, ikvm.runtime.Util.mapException(x));
435
Startup.exitMainThread();
440
private static string GetMainClassFromJarManifest(string mainClass)
442
JarFile jf = new JarFile(mainClass);
445
Manifest manifest = jf.getManifest();
446
if (manifest == null)
448
Console.Error.WriteLine("Jar file doesn't contain manifest");
451
mainClass = manifest.getMainAttributes().getValue(Attributes.Name.MAIN_CLASS);
457
if (mainClass == null)
459
Console.Error.WriteLine("Manifest doesn't contain a Main-Class.");
462
return mainClass.Replace('/', '.');