scala / bug

Scala 2 bug reports only. Please, no questions — proper bug reports only.
https://scala-lang.org
232 stars 21 forks source link

Getting "NoSuchMethodError: main" When There is One #1584

Closed scabug closed 13 years ago

scabug commented 15 years ago

How to reproduce:

  1. Enter the Scala perspective and create a New Scala Project & Give it any name
  2. Create a package, "hello", in the newly created project
  3. With package "hello" selected, run File -> New Scala Class and name it "Hello" and give it a main method exactly as follows:
    
    package hello

class Hello { def main(args:Array[String]) = println("hi world") }

 1. Now right-click Hello in the package explorer and select "Run As -> Scala Application" which will fail as expected with a `ClassNotFoundException`.
 1. Now change the Hello class to a singleton object by replacing `class` with `object` so it will look exactly as follows:
```scala
package hello

object Hello {
  def main(args:Array[String]) = println("hi world")
}
  1. Now Right-Click and select "Run As -> Scala Application" again. This should work but results in Exception in thread "main" java.lang.NoSuchMethodError: main.

Running Project -> Clean will fix the problem but the above behavior is unexpected & confuses noobs like me :)

I was able to reproduce this on my !MacBook and Vista box.

scabug commented 15 years ago

Imported From: https://issues.scala-lang.org/browse/SI-1584?orig=1 Reporter: Bret Lester (spiralhead)

scabug commented 15 years ago

@milessabin said: It looks as though the plugin is treating the stale classfile corresponding to the pre-edit class as the companion of the post-edit object and that that is preventing the generation of the static forwarders.

Cleaning is a workaround as you observe, but the plugin should be smarter about dealing with cases like this.

scabug commented 15 years ago

Beren Erchamion (beren) said: I get the same issue with Eclipse 3.4 at the latest build level as of posting.

scabug commented 15 years ago

Wolfgang Frech (wfrech) said: I see a similar, unexpected behavior:

With the scale source file

package whf.scala.ui

class ObjectWithSameNameConsoleReproducer {
  def main(args: Array[String]) = {
    println("running")
  }
}

object ObjectWithSameNameConsoleReproducer extends ObjectWithSameNameConsoleReproducer

object ObjectWithDifferentNameForConsoleReproducer extends ObjectWithSameNameConsoleReproducer

the Package Explorer shows four nodes, one for the source file and three children for the class and the two objects.

For all four nodes, the context menu Run As > Scala Application opens the Select Java Application Dialog with the pattern "**" (two asteriscs) and three matching items, the class and the two synthetic classes for the objects.

Selecting the class leads to an error dialog "Could not find the main class. Will exit." and this console message:

java.lang.NoClassDefFoundError: whf/scala/ui/ObjectWithSameNameConsoleReproduce
Caused by: java.lang.ClassNotFoundException: whf.scala.ui.ObjectWithSameNameConsoleReproduce
    at java.net.URLClassLoader$$1.run(URLClassLoader.java:200)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.net.URLClassLoader.findClass(URLClassLoader.java:188)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:306)
    at sun.misc.Launcher$$AppClassLoader.loadClass(Launcher.java:276)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:251)
    at java.lang.ClassLoader.loadClassInternal(ClassLoader.java:319)
}

Note the missing "r" in the demo class.

Selecting the synthetic class of the companion object with the _same_ name leads to an error dialog "Fatal exception ocurred. Program will exit." and this console output: 

java.lang.NoSuchMethodError: main Exception in thread "main"


Selecting the synthetic class of the object with a _different_ name works as expected. In this example, it leads to the console output

running


Cleaning the project or closing/reopening the project has no effects.

I started with a reproducer for a Swing App, with the same results. The positive case here is that the JFrame shows as expected.

package whf.scala.ui

import swing.{MainFrame, SimpleGUIApplication}

class ObjectWithSameNameGUIReproducer extends SimpleGUIApplication { val top = new MainFrame{ val text = "ObjectWithSameNameGUIReproducer" // no content } }

object ObjectWithSameNameGUIReproducer extends ObjectWithSameNameGUIReproducer

object ObjectWithDifferentNameForGUIReproducer extends ObjectWithSameNameGUIReproducer {code}

Workaround: For a main object, that is the object of a class with a main method, use a different name from its class.

Issues with the current behaviour:

1) Selecting a Scala source file, only the two objects should be shown as matching items. The class should not be shown.

2) Selecting the object within the source file, it should be launched without a selection dialog.

3) Selecting the class, the menu Run As > Scala Application should not be shown.

4) If there are two runnable/launchable objects in a selection, there Scala names should be shown, not the synthetic Java names.

5) The Launch dialog should be named with "Scala", not "Java".

6) And last but not least: A companion object with the same Scala name as its class should be launchable.

Environment:

Eclipse Version: 3.4.0 Build id: I20080617-2000

Scala Plugin 2.7.4 final dito Weaver

Java 1.6, jdk1.6.0_07

Windows XP

scabug commented 14 years ago

spiros said: This bug still exists in r19928 but it seems to me like yet another manifestation of #2443. plocinic said in #2581 that "In resident mode symbols of top level classes don't get removed which is why you get this weird behaviour even if A and B are in the same file" so I believe that the same applies here.

scabug commented 14 years ago

@milessabin said: Yes, concur with that analysis.

scabug commented 14 years ago

Uri Shani (urishani) said: Replying to [ticket:1584 spiralhead]:

Just tried newest version 2.7.7 on Eclipse 3.5. Followed instructions as in this append. Except defined it:

Object HelloWorld extends Application {
   println("Hello World!")
}

Launching as Scala application does not find static main method. Cleaning the project as recommended here resolved the issue.

scabug commented 14 years ago

spiros said: This bug appears to be fixed in r20397.

scabug commented 14 years ago

@milessabin said: Thanks for reviewing this ticket :-)

scabug commented 14 years ago

Terry Woodruff (twoodruff) said: I installed Eclipse 3.5.1 (64 bit) today along with the latest Java SDK, and followed the instructions for loading the Scala IDE (2.8 latest nightly) exactly as specified on the Scala website. Using the example code given there:

Object HelloWorld extends Application { println("Hello World!") }

I get the "main not found error". Adding an actual main declaration makes it work.

scabug commented 14 years ago

@milessabin said: You're reporting a different issue ... please check that there isn't already an open ticket for it and if not create a fresh one.