One invalid .scala file in a project seems to cause ALL of them to stop building
I am encountering an issue where it appears that if ANY .scala file is invalid then ALL .scala files stop compiling. In detail:
1> Create a new Scala project; set Project>Build Automatically on
2> Create a new Scala app; lets say Invalid.scala and put nothing but the following into it (eg delete what the template provides and put exactly the line below)
println "Hello, World"
2.1> Eclipse reports 'expected class or object definition' under problems. Fair enough.
3> Create a new Scala app; lets say Happy.scala and put a valid hello world in. Perhaps:
object Happy {
def main(args : Array[String])= println ("Hello, World")
}
3.1> Eclipse reports no problems with Happy.
4> Try to run Happy as a Scala app (eg Alt+Shift+X, S while focus in in the Happy.scala window). It says NoClassDefFoundError:
4.1> Look at your .classpath and .project files for Eclipse; conclude it should be compiling to <<yourproject>>/bin. Look into <<yourproject>>/bin. There are no files!
5> Fix the compile error in Invalid.scala, such as by deleting the invalid line so it's just a blank file. Save Invalid.scala.
5.1> Look into <<yourproject>>/bin. There is now Happy.class and Happy$.class.
6> Try to run Happy again. It works now.
It is even more confusing if you create Happy, it compiles and runs, you create Invalid, it doesn't compile or run, you go back to Happy and it still appears to compile and run (because the .class file was built before we created Invalid), then you modify Happy and suddenly it doesn't work. One is inclined to believe our last change made since it worked is responsible for the breakage but this is in fact not the case.
My expected result was that if Invalid.scala was invalid and Happy.scala was valid then Happy would be compiled, /bin would contain the .class files for Happy, and I'd be able to run Happy just fine.
My environment is:
- Eclipse Galileo 3.5.2 for Java (Build id: 20100218-1602 from About Eclipse), plus the Scala nightly master 2.8.1.final (build-20110222-050023 based on the directories inside org.scala-ide.sdt.update-site.zip). I used the .zip because the update site didn't work for me on either Galileo or Helios; I had to download the .zip to get it to install.
- java -version:
java version "1.6.0_22"
Java(TM) SE Runtime Environment (build 1.6.0_22-b04)
Java HotSpot(TM) Client VM (build 17.1-b03, mixed mode, sharing)
- Windows 7 32 bit
My apologies if this is a duplicate or a configuration/users fault issue but I didn't seem to see anything covering this exact issue and it confused the hell out of me when I first installed ScalaIDE. Worse, it gives an unfortunate first impression of the tool to have something that feels like a bug come up within five minutes of installing. Note that I have filed this as a Defect, though if this is presently working as intended it should perhaps be reclassified as an enhancement request. Further note that I am not sure if Branch: Master is correct; it seemed the most reasonable of the options available.
1> Create a new Scala project; set Project>Build Automatically on
2> Create a new Scala app; lets say Invalid.scala and put nothing but the following into it (eg delete what the template provides and put exactly the line below)
println "Hello, World"
2.1> Eclipse reports 'expected class or object definition' under problems. Fair enough.
3> Create a new Scala app; lets say Happy.scala and put a valid hello world in. Perhaps:
object Happy {
def main(args : Array[String])= println ("Hello, World")
}
3.1> Eclipse reports no problems with Happy.
4> Try to run Happy as a Scala app (eg Alt+Shift+X, S while focus in in the Happy.scala window). It says NoClassDefFoundError:
java.lang.NoClassDefFoundError: Happy
Caused by: java.lang.ClassNotFoundException: Happy
at java.net.URLClassLoader$1.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(Unknown Source)
at java.lang.ClassLoader.loadClass(Unknown Source)
at sun.misc.Launcher$AppClassLoader.loadClass(Unknown Source)
at java.lang.ClassLoader.loadClass(Unknown Source)
Exception in thread "main"
4.1> Look at your .classpath and .project files for Eclipse; conclude it should be compiling to <<yourproject>>/bin. Look into <<yourproject>>/bin. There are no files!
5> Fix the compile error in Invalid.scala, such as by deleting the invalid line so it's just a blank file. Save Invalid.scala.
5.1> Look into <<yourproject>>/bin. There is now Happy.class and Happy$.class.
6> Try to run Happy again. It works now.
It is even more confusing if you create Happy, it compiles and runs, you create Invalid, it doesn't compile or run, you go back to Happy and it still appears to compile and run (because the .class file was built before we created Invalid), then you modify Happy and suddenly it doesn't work. One is inclined to believe our last change made since it worked is responsible for the breakage but this is in fact not the case.
My expected result was that if Invalid.scala was invalid and Happy.scala was valid then Happy would be compiled, /bin would contain the .class files for Happy, and I'd be able to run Happy just fine.
My environment is:
- Eclipse Galileo 3.5.2 for Java (Build id: 20100218-1602 from About Eclipse), plus the Scala nightly master 2.8.1.final (build-20110222-050023 based on the directories inside org.scala-ide.sdt.update-site.zip). I used the .zip because the update site didn't work for me on either Galileo or Helios; I had to download the .zip to get it to install.
- java -version:
java version "1.6.0_22"
Java(TM) SE Runtime Environment (build 1.6.0_22-b04)
Java HotSpot(TM) Client VM (build 17.1-b03, mixed mode, sharing)
- Windows 7 32 bit
My apologies if this is a duplicate or a configuration/users fault issue but I didn't seem to see anything covering this exact issue and it confused the hell out of me when I first installed ScalaIDE. Worse, it gives an unfortunate first impression of the tool to have something that feels like a bug come up within five minutes of installing. Note that I have filed this as a Defect, though if this is presently working as intended it should perhaps be reclassified as an enhancement request. Further note that I am not sure if Branch: Master is correct; it seemed the most reasonable of the options available.
Leave a comment
on 2011-02-23 09:42 *
By Iulian Dragos
This behavior comes from the Scala compiler, same things happens on the command line. I agree it's not nice, but I don't see an easy solution. Most of the times the other files rely on the failing one, so you'd get other errors and still no classfiles. Eclipse relies on the compiler for all its functionality, so I don't see this ever been 'fixed'.
on 2011-02-23 19:10 *
By rod.sheeter
Hmm; I think it can be done at least somewhat better than the current behavior, with the somewhat significant caveat this is not at all my area of expertise. It seems to me the key is would be to try to compile only the modified item and just pull the existing .class files onto classpath for the dependencies stuff. Eg if user modifies file A.scala our Eclipse builder is notified of the file that I changed. If it remembers that it's done a full build already it can issue an incremental compile.
For example:
1> I boot Eclipse with everything valid and do a clean. All my files now have up to date .class files in /bin.
2> I modify ModifyMe.scala. Eclipse issues a scalac command similar to:
scalac ModifyMe.scala -classpath .\bin -d .\bin
2.1> Note that the only file we recompile is ModifyMe; the .class files for it's dependencies come from \bin
3> I modify Broken.scala to be ... broken. The builder issues scalac for just Broken.scala, it fails, we know that Broken.scala is non-compilable.
4> I modify ModifyMe.scala (doesn't depend on Broken.scala; may depend on other files); it compiles just ModifyMe without issue
4.1> ...and here it gets slightly tricky. It could be that when we modified ModifyMe we fixed Broken (eg Broken was calling a method that didn't exist on ModifyMe, we just created it so now Broken is compilable). Perhaps we have to retry broken files whenever something successfully compiles?
For example:
1> I boot Eclipse with everything valid and do a clean. All my files now have up to date .class files in /bin.
2> I modify ModifyMe.scala. Eclipse issues a scalac command similar to:
scalac ModifyMe.scala -classpath .\bin -d .\bin
2.1> Note that the only file we recompile is ModifyMe; the .class files for it's dependencies come from \bin
3> I modify Broken.scala to be ... broken. The builder issues scalac for just Broken.scala, it fails, we know that Broken.scala is non-compilable.
4> I modify ModifyMe.scala (doesn't depend on Broken.scala; may depend on other files); it compiles just ModifyMe without issue
4.1> ...and here it gets slightly tricky. It could be that when we modified ModifyMe we fixed Broken (eg Broken was calling a method that didn't exist on ModifyMe, we just created it so now Broken is compilable). Perhaps we have to retry broken files whenever something successfully compiles?
on 2011-02-24 11:38 *
By ruediger.keller
I see this behavior a lot in my projects, too, and I think that it is a serious problem.
It should definitely be a goal to fix this at least in the long run, IMHO.
In the past this problem was even worse, because often the erroneous file was not even reported anywhere. This usually happened when moving files in the package explorer. But I believe at least that last bug is fixed by now.
It should definitely be a goal to fix this at least in the long run, IMHO.
In the past this problem was even worse, because often the erroneous file was not even reported anywhere. This usually happened when moving files in the package explorer. But I believe at least that last bug is fixed by now.
Updating tickets (#1000199, #1000200, #1000201, #1000204, #1000205, #1000209, #1000210, #1000211, #1000212, #1000215, #1000217, #1000218, #1000220, #1000222, #1000226, #1000227, #1000228, #1000230, #1000231, #1000232, #1000233, #1000235, #1000236, #1000237, #1000239, #1000240, #1000241, #1000242, #1000243, #1000244, #1000248, #1000249, #1000252, #1000253, #1000254, #1000255, #1000256, #1000258, #1000259, #1000032, #1000059, #1000062, #1000163, #1000197, #1000216, #1000221, #1000224, #1000121, #1000175, #1000219, #1000251, #1000069, #1000195, #1000213, #1000223, #1000006, #1000021, #1000038, #1000048, #1000051, #1000052, #1000075, #1000103, #1000109, #1000115, #1000119, #1000156, #1000186, #1000207, #1000238, #1000262, #1000263, #380, #389, #683, #1238, #1331, #1635, #1645, #1715, #1729, #1744, #1783, #1839, #1869, #1885, #1890, #1902, #1918, #1919, #1924, #1925, #1946, #1964, #1991, #2131, #2233, #2342, #2348, #2408)
This isn't something the Scala IDE can fix, unfortunately it is the way the Scala compiler works.