Allow main class to be non-public. Fixes #883.

This commit is contained in:
Mark Harrah 2013-09-26 09:42:30 -04:00
parent 72125e73ce
commit b8b6426cf9
3 changed files with 13 additions and 2 deletions

View File

@ -14,7 +14,13 @@ class Discovery(baseClasses: Set[String], annotations: Set[String])
def apply(d: Definition): Discovered =
d match
{
case c: ClassLike if isPublic(c) && isConcrete(c.modifiers) => discover(c)
case c: ClassLike if isConcrete(c.modifiers) =>
if(isPublic(c))
discover(c)
else if(isModule(c) && hasMainMethod(c)) // jvm does not require a main class to be public
new Discovered(Set.empty, Set.empty, true, true)
else
Discovered.empty
case _ => Discovered.empty
}
def discover(c: ClassLike): Discovered =
@ -24,6 +30,7 @@ class Discovery(baseClasses: Set[String], annotations: Set[String])
val module = isModule(c)
new Discovered( bases(c.name, c.structure.parents), onClass ++ onDefs, module && hasMainMethod(c), module )
}
def bases(own: String, c: Seq[Type]): Set[String] =
(own +: c.flatMap(simpleName)).filter(baseClasses).toSet

View File

@ -76,6 +76,9 @@ class Run(instance: ScalaInstance, trapExit: Boolean, nativeTmp: File) extends S
{
val mainClass = Class.forName(mainClassName, true, loader)
val method = mainClass.getMethod("main", classOf[Array[String]])
// jvm allows the actual main class to be non-public and to run a method in the non-public class,
// we need to make it accessible
method.setAccessible(true)
val modifiers = method.getModifiers
if(!isPublic(modifiers)) throw new NoSuchMethodException(mainClassName + ".main is not public")
if(!isStatic(modifiers)) throw new NoSuchMethodException(mainClassName + ".main is not static")

View File

@ -1,4 +1,5 @@
public class A{
// Java allows the main class to have default access, test that here
class A{
public static void main(String... args){
}