2002-12-18 19:00:25 +03:00
|
|
|
/*
|
2006-01-31 13:13:12 +03:00
|
|
|
Copyright (C) 2002, 2003, 2004, 2005, 2006 Jeroen Frijters
|
2002-12-18 19:00:25 +03:00
|
|
|
|
|
|
|
This software is provided 'as-is', without any express or implied
|
|
|
|
warranty. In no event will the authors be held liable for any damages
|
|
|
|
arising from the use of this software.
|
|
|
|
|
|
|
|
Permission is granted to anyone to use this software for any purpose,
|
|
|
|
including commercial applications, and to alter it and redistribute it
|
|
|
|
freely, subject to the following restrictions:
|
|
|
|
|
|
|
|
1. The origin of this software must not be misrepresented; you must not
|
|
|
|
claim that you wrote the original software. If you use this software
|
|
|
|
in a product, an acknowledgment in the product documentation would be
|
|
|
|
appreciated but is not required.
|
|
|
|
2. Altered source versions must be plainly marked as such, and must not be
|
|
|
|
misrepresented as being the original software.
|
|
|
|
3. This notice may not be removed or altered from any source distribution.
|
|
|
|
|
|
|
|
Jeroen Frijters
|
|
|
|
jeroen@frijters.net
|
|
|
|
|
|
|
|
*/
|
|
|
|
using System;
|
|
|
|
using System.IO;
|
|
|
|
using System.Reflection;
|
|
|
|
using System.Reflection.Emit;
|
|
|
|
using System.Collections;
|
2004-09-15 17:35:44 +04:00
|
|
|
using System.Collections.Specialized;
|
2002-12-29 19:27:00 +03:00
|
|
|
using System.Text;
|
2004-09-09 15:17:55 +04:00
|
|
|
using IKVM.Internal;
|
2002-12-18 19:00:25 +03:00
|
|
|
|
2006-08-17 11:33:38 +04:00
|
|
|
using ikvm.runtime;
|
2002-12-18 19:00:25 +03:00
|
|
|
using java.lang.reflect;
|
|
|
|
using java.net;
|
|
|
|
using java.util.jar;
|
|
|
|
using java.io;
|
|
|
|
|
2007-05-18 10:06:52 +04:00
|
|
|
using Console = System.Console;
|
|
|
|
|
2002-12-18 19:00:25 +03:00
|
|
|
public class Starter
|
|
|
|
{
|
|
|
|
private class Timer
|
|
|
|
{
|
|
|
|
private static Timer t;
|
|
|
|
private DateTime now = DateTime.Now;
|
|
|
|
|
|
|
|
internal Timer()
|
|
|
|
{
|
|
|
|
t = this;
|
|
|
|
}
|
|
|
|
|
|
|
|
~Timer()
|
|
|
|
{
|
|
|
|
Console.WriteLine(DateTime.Now - now);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2003-12-20 01:19:18 +03:00
|
|
|
private class SaveAssemblyShutdownHook : java.lang.Thread
|
|
|
|
{
|
|
|
|
private java.lang.Class clazz;
|
|
|
|
|
|
|
|
internal SaveAssemblyShutdownHook(java.lang.Class clazz)
|
2004-09-27 14:17:34 +04:00
|
|
|
: base("SaveAssemblyShutdownHook")
|
2003-12-20 01:19:18 +03:00
|
|
|
{
|
|
|
|
this.clazz = clazz;
|
|
|
|
}
|
|
|
|
|
|
|
|
public override void run()
|
|
|
|
{
|
2004-08-17 13:05:21 +04:00
|
|
|
System.Threading.Thread.CurrentThread.Priority = System.Threading.ThreadPriority.AboveNormal;
|
2003-12-24 14:51:41 +03:00
|
|
|
Console.Error.WriteLine("Saving dynamic assembly...");
|
|
|
|
try
|
|
|
|
{
|
2006-09-14 16:55:25 +04:00
|
|
|
IKVM.Internal.Starter.SaveDebugImage();
|
2004-04-23 18:21:43 +04:00
|
|
|
Console.Error.WriteLine("Saving done.");
|
2003-12-24 14:51:41 +03:00
|
|
|
}
|
|
|
|
catch(Exception x)
|
|
|
|
{
|
|
|
|
Console.Error.WriteLine(x);
|
2004-03-20 16:25:08 +03:00
|
|
|
Console.Error.WriteLine(new System.Diagnostics.StackTrace(x, true));
|
2003-12-24 14:51:41 +03:00
|
|
|
System.Diagnostics.Debug.Assert(false, x.ToString());
|
|
|
|
}
|
2003-12-20 01:19:18 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2004-04-02 12:13:01 +04:00
|
|
|
private class WaitShutdownHook : java.lang.Thread
|
|
|
|
{
|
2004-09-27 14:17:34 +04:00
|
|
|
internal WaitShutdownHook()
|
|
|
|
: base("WaitShutdownHook")
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
2004-04-02 12:13:01 +04:00
|
|
|
public override void run()
|
|
|
|
{
|
|
|
|
Console.Error.WriteLine("IKVM runtime terminated. Waiting for Ctrl+C...");
|
|
|
|
for(;;)
|
|
|
|
{
|
|
|
|
System.Threading.Thread.Sleep(System.Threading.Timeout.Infinite);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2002-12-18 19:00:25 +03:00
|
|
|
[STAThread] // NOTE this is here because otherwise SWT's RegisterDragDrop (a COM thing) doesn't work
|
2004-10-19 17:43:55 +04:00
|
|
|
[IKVM.Attributes.HideFromJava]
|
2002-12-18 19:00:25 +03:00
|
|
|
static int Main(string[] args)
|
|
|
|
{
|
2004-03-08 18:18:47 +03:00
|
|
|
Tracer.EnableTraceForDebug();
|
2004-10-19 17:43:55 +04:00
|
|
|
Hashtable props = new Hashtable();
|
2006-08-17 12:14:47 +04:00
|
|
|
string classpath = Environment.GetEnvironmentVariable("CLASSPATH");
|
|
|
|
if(classpath == null || classpath == "")
|
|
|
|
{
|
|
|
|
classpath = ".";
|
|
|
|
}
|
|
|
|
props["java.class.path"] = classpath;
|
2002-12-18 19:00:25 +03:00
|
|
|
bool jar = false;
|
|
|
|
bool saveAssembly = false;
|
2004-09-05 13:37:58 +04:00
|
|
|
bool saveAssemblyX = false;
|
2004-04-02 12:13:01 +04:00
|
|
|
bool waitOnExit = false;
|
2006-01-31 13:13:12 +03:00
|
|
|
bool showVersion = false;
|
2002-12-18 19:00:25 +03:00
|
|
|
string mainClass = null;
|
2007-05-31 12:21:14 +04:00
|
|
|
int vmargsIndex = -1;
|
2002-12-18 19:00:25 +03:00
|
|
|
for(int i = 0; i < args.Length; i++)
|
|
|
|
{
|
|
|
|
if(args[i][0] == '-')
|
|
|
|
{
|
2003-03-17 17:02:46 +03:00
|
|
|
if(args[i] == "-help" || args[i] == "-?")
|
2002-12-18 19:00:25 +03:00
|
|
|
{
|
|
|
|
break;
|
|
|
|
}
|
2003-03-17 17:02:46 +03:00
|
|
|
else if(args[i] == "-Xsave")
|
2002-12-18 19:00:25 +03:00
|
|
|
{
|
|
|
|
saveAssembly = true;
|
2006-04-10 13:09:09 +04:00
|
|
|
IKVM.Internal.Starter.PrepareForSaveDebugImage();
|
2002-12-18 19:00:25 +03:00
|
|
|
}
|
2004-09-05 13:37:58 +04:00
|
|
|
else if(args[i] == "-XXsave")
|
|
|
|
{
|
|
|
|
saveAssemblyX = true;
|
2006-04-10 13:09:09 +04:00
|
|
|
IKVM.Internal.Starter.PrepareForSaveDebugImage();
|
2004-09-05 13:37:58 +04:00
|
|
|
}
|
2003-03-17 17:02:46 +03:00
|
|
|
else if(args[i] == "-Xtime")
|
2002-12-18 19:00:25 +03:00
|
|
|
{
|
|
|
|
new Timer();
|
|
|
|
}
|
2004-04-02 12:13:01 +04:00
|
|
|
else if(args[i] == "-Xwait")
|
|
|
|
{
|
|
|
|
waitOnExit = true;
|
|
|
|
}
|
2004-07-10 11:19:42 +04:00
|
|
|
else if(args[i] == "-Xbreak")
|
|
|
|
{
|
|
|
|
System.Diagnostics.Debugger.Break();
|
|
|
|
}
|
2002-12-18 19:00:25 +03:00
|
|
|
else if(args[i] == "-jar")
|
|
|
|
{
|
|
|
|
jar = true;
|
|
|
|
}
|
2003-07-21 16:12:40 +04:00
|
|
|
else if(args[i] == "-version")
|
|
|
|
{
|
2006-08-17 11:33:38 +04:00
|
|
|
Console.WriteLine(Startup.getVersionAndCopyrightInfo());
|
2006-01-31 13:13:12 +03:00
|
|
|
Console.WriteLine();
|
2005-03-11 16:56:44 +03:00
|
|
|
Console.WriteLine("CLR version: {0} ({1} bit)", Environment.Version, IntPtr.Size * 8);
|
2006-09-28 22:56:00 +04:00
|
|
|
System.Type type = System.Type.GetType("Mono.Runtime");
|
|
|
|
if(type != null)
|
|
|
|
{
|
|
|
|
Console.WriteLine("Mono version: {0}", type.InvokeMember("GetDisplayName", BindingFlags.InvokeMethod | BindingFlags.Static | BindingFlags.NonPublic, null, null, new object[0]));
|
|
|
|
}
|
2003-07-21 16:12:40 +04:00
|
|
|
foreach(Assembly asm in AppDomain.CurrentDomain.GetAssemblies())
|
|
|
|
{
|
|
|
|
Console.WriteLine("{0}: {1}", asm.GetName().Name, asm.GetName().Version);
|
|
|
|
}
|
2007-08-16 16:57:32 +04:00
|
|
|
string ver = java.lang.System.getProperty("gnu.classpath.version");
|
|
|
|
if(ver != null)
|
|
|
|
{
|
|
|
|
Console.WriteLine("GNU Classpath version: {0}", ver);
|
|
|
|
}
|
|
|
|
ver = java.lang.System.getProperty("openjdk.version");
|
|
|
|
if(ver != null)
|
|
|
|
{
|
|
|
|
Console.WriteLine("OpenJDK version: {0}", ver);
|
|
|
|
}
|
2003-07-21 16:12:40 +04:00
|
|
|
return 0;
|
|
|
|
}
|
2006-01-31 13:13:12 +03:00
|
|
|
else if(args[i] == "-showversion")
|
|
|
|
{
|
|
|
|
showVersion = true;
|
|
|
|
}
|
2002-12-18 19:00:25 +03:00
|
|
|
else if(args[i].StartsWith("-D"))
|
|
|
|
{
|
|
|
|
string[] keyvalue = args[i].Substring(2).Split('=');
|
|
|
|
if(keyvalue.Length != 2)
|
|
|
|
{
|
|
|
|
keyvalue = new string[] { keyvalue[0], "" };
|
|
|
|
}
|
2004-09-05 13:37:58 +04:00
|
|
|
props[keyvalue[0]] = keyvalue[1];
|
2002-12-18 19:00:25 +03:00
|
|
|
}
|
2004-10-04 23:30:53 +04:00
|
|
|
else if(args[i] == "-ea" || args[i] == "-enableassertions")
|
|
|
|
{
|
2007-09-12 10:51:37 +04:00
|
|
|
IKVM.Runtime.Assertions.EnableAssertions();
|
2004-10-04 23:30:53 +04:00
|
|
|
}
|
|
|
|
else if(args[i] == "-da" || args[i] == "-disableassertions")
|
|
|
|
{
|
2007-09-12 10:51:37 +04:00
|
|
|
IKVM.Runtime.Assertions.DisableAssertions();
|
|
|
|
}
|
|
|
|
else if(args[i] == "-esa" || args[i] == "-enablesystemassertions")
|
|
|
|
{
|
|
|
|
IKVM.Runtime.Assertions.EnableSystemAssertions();
|
|
|
|
}
|
|
|
|
else if(args[i] == "-dsa" || args[i] == "-disablesystemassertions")
|
|
|
|
{
|
|
|
|
IKVM.Runtime.Assertions.DisableSystemAssertions();
|
2004-10-04 23:30:53 +04:00
|
|
|
}
|
|
|
|
else if(args[i].StartsWith("-ea:") || args[i].StartsWith("-enableassertions:"))
|
|
|
|
{
|
2007-09-12 10:51:37 +04:00
|
|
|
IKVM.Runtime.Assertions.EnableAssertions(args[i].Substring(args[i].IndexOf(':') + 1));
|
2004-10-04 23:30:53 +04:00
|
|
|
}
|
|
|
|
else if(args[i].StartsWith("-da:") || args[i].StartsWith("-disableassertions:"))
|
|
|
|
{
|
2007-09-12 10:51:37 +04:00
|
|
|
IKVM.Runtime.Assertions.DisableAssertions(args[i].Substring(args[i].IndexOf(':') + 1));
|
2004-10-04 23:30:53 +04:00
|
|
|
}
|
2002-12-18 19:00:25 +03:00
|
|
|
else if(args[i] == "-cp" || args[i] == "-classpath")
|
|
|
|
{
|
2004-09-05 13:37:58 +04:00
|
|
|
props["java.class.path"] = args[++i];
|
2002-12-18 19:00:25 +03:00
|
|
|
}
|
2004-03-08 18:18:47 +03:00
|
|
|
else if(args[i].StartsWith("-Xtrace:"))
|
2003-03-17 17:02:46 +03:00
|
|
|
{
|
2004-03-08 18:18:47 +03:00
|
|
|
Tracer.SetTraceLevel(args[i].Substring(8));
|
|
|
|
}
|
|
|
|
else if(args[i].StartsWith("-Xmethodtrace:"))
|
|
|
|
{
|
|
|
|
Tracer.HandleMethodTrace(args[i].Substring(14));
|
2003-03-17 17:02:46 +03:00
|
|
|
}
|
2005-07-14 16:28:45 +04:00
|
|
|
else if(args[i].StartsWith("-Xms")
|
|
|
|
|| args[i].StartsWith("-Xmx")
|
|
|
|
|| args[i].StartsWith("-Xss")
|
|
|
|
|| args[i] == "-Xmixed"
|
|
|
|
|| args[i] == "-Xint"
|
|
|
|
|| args[i] == "-Xnoclassgc"
|
|
|
|
|| args[i] == "-Xincgc"
|
|
|
|
|| args[i] == "-Xbatch"
|
|
|
|
|| args[i] == "-Xfuture"
|
|
|
|
|| args[i] == "-Xrs"
|
|
|
|
|| args[i] == "-Xcheck:jni"
|
|
|
|
|| args[i] == "-Xshare:off"
|
|
|
|
|| args[i] == "-Xshare:auto"
|
|
|
|
|| args[i] == "-Xshare:on"
|
|
|
|
)
|
|
|
|
{
|
|
|
|
Console.Error.WriteLine("Unsupported option ignored: {0}", args[i]);
|
|
|
|
}
|
2002-12-18 19:00:25 +03:00
|
|
|
else
|
|
|
|
{
|
|
|
|
Console.Error.WriteLine("{0}: illegal argument", args[i]);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
mainClass = args[i];
|
2007-05-31 12:21:14 +04:00
|
|
|
vmargsIndex = i + 2;
|
2002-12-18 19:00:25 +03:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
2006-01-31 13:13:12 +03:00
|
|
|
if(mainClass == null || showVersion)
|
|
|
|
{
|
2006-08-17 11:33:38 +04:00
|
|
|
Console.Error.WriteLine(Startup.getVersionAndCopyrightInfo());
|
2006-01-31 13:13:12 +03:00
|
|
|
Console.Error.WriteLine();
|
|
|
|
}
|
2002-12-18 19:00:25 +03:00
|
|
|
if(mainClass == null)
|
|
|
|
{
|
|
|
|
Console.Error.WriteLine("usage: ikvm [-options] <class> [args...]");
|
|
|
|
Console.Error.WriteLine(" (to execute a class)");
|
|
|
|
Console.Error.WriteLine(" or ikvm -jar [-options] <jarfile> [args...]");
|
|
|
|
Console.Error.WriteLine(" (to execute a jar file)");
|
|
|
|
Console.Error.WriteLine();
|
|
|
|
Console.Error.WriteLine("where options include:");
|
2004-09-15 17:35:44 +04:00
|
|
|
Console.Error.WriteLine(" -? -help Display this message");
|
2004-10-04 23:30:53 +04:00
|
|
|
Console.Error.WriteLine(" -version Display IKVM and runtime version");
|
2006-01-31 13:13:12 +03:00
|
|
|
Console.Error.WriteLine(" -showversion Display version and continue running");
|
2003-03-17 17:02:46 +03:00
|
|
|
Console.Error.WriteLine(" -cp -classpath <directories and zip/jar files separated by {0}>", Path.PathSeparator);
|
2004-09-15 17:35:44 +04:00
|
|
|
Console.Error.WriteLine(" Set search path for application classes and resources");
|
|
|
|
Console.Error.WriteLine(" -D<name>=<value> Set a system property");
|
2004-10-04 23:30:53 +04:00
|
|
|
Console.Error.WriteLine(" -ea[:<packagename>...|:<classname>]");
|
|
|
|
Console.Error.WriteLine(" -enableassertions[:<packagename>...|:<classname>]");
|
|
|
|
Console.Error.WriteLine(" Enable assertions.");
|
|
|
|
Console.Error.WriteLine(" -da[:<packagename>...|:<classname>]");
|
|
|
|
Console.Error.WriteLine(" -disableassertions[:<packagename>...|:<classname>]");
|
|
|
|
Console.Error.WriteLine(" Disable assertions");
|
2004-09-15 17:35:44 +04:00
|
|
|
Console.Error.WriteLine(" -Xsave Save the generated assembly (for debugging)");
|
|
|
|
Console.Error.WriteLine(" -Xtime Time the execution");
|
2004-03-08 18:18:47 +03:00
|
|
|
Console.Error.WriteLine(" -Xtrace:<string> Displays all tracepoints with the given name");
|
2004-10-04 23:30:53 +04:00
|
|
|
Console.Error.WriteLine(" -Xmethodtrace:<string>");
|
|
|
|
Console.Error.WriteLine(" Builds method trace into the specified output methods");
|
2004-04-02 12:13:01 +04:00
|
|
|
Console.Error.WriteLine(" -Xwait Keep process hanging around after exit");
|
2004-10-04 23:30:53 +04:00
|
|
|
Console.Error.WriteLine(" -Xbreak Trigger a user defined breakpoint at startup");
|
2002-12-18 19:00:25 +03:00
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
try
|
|
|
|
{
|
2004-09-27 14:17:34 +04:00
|
|
|
if(jar)
|
|
|
|
{
|
|
|
|
props["java.class.path"] = mainClass;
|
|
|
|
}
|
2006-08-17 11:33:38 +04:00
|
|
|
Startup.setProperties(props);
|
|
|
|
Startup.enterMainThread();
|
2007-05-31 12:21:14 +04:00
|
|
|
// HACK Starup.glob() uses Java code, so we need to do this after we've initialized
|
|
|
|
string[] vmargs = Startup.glob(vmargsIndex);
|
|
|
|
if (jar)
|
2002-12-18 19:00:25 +03:00
|
|
|
{
|
|
|
|
JarFile jf = new JarFile(mainClass);
|
|
|
|
try
|
|
|
|
{
|
2005-12-19 18:12:49 +03:00
|
|
|
Manifest manifest = jf.getManifest();
|
|
|
|
if(manifest == null)
|
|
|
|
{
|
|
|
|
Console.Error.WriteLine("Jar file doesn't contain manifest");
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
mainClass = manifest.getMainAttributes().getValue(Attributes.Name.MAIN_CLASS);
|
2002-12-18 19:00:25 +03:00
|
|
|
}
|
|
|
|
finally
|
|
|
|
{
|
|
|
|
jf.close();
|
|
|
|
}
|
|
|
|
if(mainClass == null)
|
|
|
|
{
|
|
|
|
Console.Error.WriteLine("Manifest doesn't contain a Main-Class.");
|
|
|
|
return 1;
|
|
|
|
}
|
2005-12-19 18:12:49 +03:00
|
|
|
mainClass = mainClass.Replace('/', '.');
|
2002-12-18 19:00:25 +03:00
|
|
|
}
|
2004-08-17 13:05:21 +04:00
|
|
|
java.lang.Class clazz = java.lang.Class.forName(mainClass, true, java.lang.ClassLoader.getSystemClassLoader());
|
2006-08-20 13:15:23 +04:00
|
|
|
try
|
2002-12-18 19:00:25 +03:00
|
|
|
{
|
2006-08-20 13:15:23 +04:00
|
|
|
Method method = FindMainMethod(clazz);
|
|
|
|
if(method == null)
|
2004-03-16 20:10:09 +03:00
|
|
|
{
|
2006-08-20 13:15:23 +04:00
|
|
|
throw new java.lang.NoSuchMethodError("main");
|
2002-12-18 19:00:25 +03:00
|
|
|
}
|
2006-08-20 13:15:23 +04:00
|
|
|
else if(!Modifier.isPublic(method.getModifiers()))
|
2002-12-18 19:00:25 +03:00
|
|
|
{
|
2006-08-20 13:15:23 +04:00
|
|
|
Console.Error.WriteLine("Main method not public.");
|
2002-12-18 19:00:25 +03:00
|
|
|
}
|
2006-08-20 13:15:23 +04:00
|
|
|
else
|
2004-09-05 13:37:58 +04:00
|
|
|
{
|
2006-08-20 13:15:23 +04:00
|
|
|
// if clazz isn't public, we can still call main
|
|
|
|
method.setAccessible(true);
|
|
|
|
if(saveAssembly)
|
|
|
|
{
|
|
|
|
java.lang.Runtime.getRuntime().addShutdownHook(new SaveAssemblyShutdownHook(clazz));
|
|
|
|
}
|
|
|
|
if(waitOnExit)
|
|
|
|
{
|
|
|
|
java.lang.Runtime.getRuntime().addShutdownHook(new WaitShutdownHook());
|
|
|
|
}
|
|
|
|
try
|
2004-09-05 13:37:58 +04:00
|
|
|
{
|
2006-08-20 13:15:23 +04:00
|
|
|
method.invoke(null, new object[] { vmargs });
|
|
|
|
return 0;
|
2004-09-05 13:37:58 +04:00
|
|
|
}
|
2006-08-20 13:15:23 +04:00
|
|
|
catch(InvocationTargetException x)
|
|
|
|
{
|
|
|
|
throw x.getCause();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
finally
|
|
|
|
{
|
|
|
|
if(saveAssemblyX)
|
|
|
|
{
|
2006-09-14 16:55:25 +04:00
|
|
|
IKVM.Internal.Starter.SaveDebugImage();
|
2004-09-05 13:37:58 +04:00
|
|
|
}
|
2002-12-18 19:00:25 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
catch(System.Exception x)
|
|
|
|
{
|
|
|
|
java.lang.Thread thread = java.lang.Thread.currentThread();
|
2006-08-17 11:33:38 +04:00
|
|
|
thread.getThreadGroup().uncaughtException(thread, ikvm.runtime.Util.mapException(x));
|
2002-12-18 19:00:25 +03:00
|
|
|
}
|
2003-12-20 01:19:18 +03:00
|
|
|
finally
|
|
|
|
{
|
2006-08-17 11:33:38 +04:00
|
|
|
Startup.exitMainThread();
|
2003-12-20 01:19:18 +03:00
|
|
|
}
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
private static Method FindMainMethod(java.lang.Class clazz)
|
|
|
|
{
|
2005-02-23 15:56:15 +03:00
|
|
|
// HACK without this hack, clazz.getDeclaredMethods would throw a NoClassDefFoundError if any
|
|
|
|
// of the methods in the class had an unloadable parameter type, but we don't want that.
|
2006-04-10 13:09:09 +04:00
|
|
|
IKVM.Internal.Starter.EnableReflectionOnMethodsWithUnloadableTypeParameters = true;
|
2005-02-23 15:56:15 +03:00
|
|
|
try
|
2003-12-20 01:19:18 +03:00
|
|
|
{
|
2005-02-23 15:56:15 +03:00
|
|
|
while(clazz != null)
|
2003-12-20 01:19:18 +03:00
|
|
|
{
|
2005-02-23 15:56:15 +03:00
|
|
|
foreach(Method m in clazz.getDeclaredMethods())
|
2003-12-20 01:19:18 +03:00
|
|
|
{
|
2005-02-23 15:56:15 +03:00
|
|
|
if(m.getName() == "main" && m.getReturnType() == java.lang.Void.TYPE)
|
2003-12-20 01:19:18 +03:00
|
|
|
{
|
2005-02-23 15:56:15 +03:00
|
|
|
java.lang.Class[] parameters = m.getParameterTypes();
|
|
|
|
if(parameters.Length == 1 && parameters[0] == java.lang.Class.forName("[Ljava.lang.String;"))
|
|
|
|
{
|
|
|
|
return m;
|
|
|
|
}
|
2003-12-20 01:19:18 +03:00
|
|
|
}
|
|
|
|
}
|
2005-02-23 15:56:15 +03:00
|
|
|
clazz = clazz.getSuperclass();
|
2003-12-20 01:19:18 +03:00
|
|
|
}
|
2005-02-23 15:56:15 +03:00
|
|
|
return null;
|
|
|
|
}
|
|
|
|
finally
|
|
|
|
{
|
2006-04-10 13:09:09 +04:00
|
|
|
IKVM.Internal.Starter.EnableReflectionOnMethodsWithUnloadableTypeParameters = false;
|
2003-12-20 01:19:18 +03:00
|
|
|
}
|
2002-12-18 19:00:25 +03:00
|
|
|
}
|
|
|
|
}
|