Some Eclipse Foundation services are deprecated, or will be soon. Please ensure you've read this important communication.
Bug 313790 - eclipse compiler does not reject incomplete programs, creates fake .class files instead
Summary: eclipse compiler does not reject incomplete programs, creates fake .class fil...
Status: RESOLVED WONTFIX
Alias: None
Product: JDT
Classification: Eclipse Project
Component: Core (show other bugs)
Version: 3.6   Edit
Hardware: All Linux
: P3 normal (vote)
Target Milestone: ---   Edit
Assignee: Olivier Thomann CLA
QA Contact:
URL:
Whiteboard:
Keywords:
Depends on:
Blocks:
 
Reported: 2010-05-20 14:41 EDT by Godmar Back CLA
Modified: 2010-05-27 05:33 EDT (History)
5 users (show)

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Godmar Back CLA 2010-05-20 14:41:40 EDT
Build Identifier: M20060921-0945

To whoever is seeing mysterious runtime errors such as "java.lang.Error: Unresolved compilation problems:" 

If your code causes a compilation error, Eclipse does not abort compilation like a compiler it should, it hides the error by creating a fake class that throws this Error in its constructor. Subsequently, you will be wasting your time running and debugging code you never wrote.

To whoever came up with this ingenuous idea: please respect basic software engineering custom: edit-compile-run. Not edit-"eclipse compiles what it wants"-"run a mix of what you wrote and Eclipse decides to generate"

Discovering this, I wanted to disable this behavior. I did not see an Option under Project -> Java Compiler.



Reproducible: Always

Steps to Reproduce:
1. Write a class implementing javax.servlet.ServletContextListener
2. Accidentally delete servlet-api.jar from WEB-INF/lib
3. Leave Eclipse unattended with "Automatic Project Build" turned on.
4. Waste 2 hours figuring out mysterious Tomcat log messages such as:

SEVERE: Error configuring application listener of class org.me.Clazz$ShutdownListener
java.lang.Error: Unresolved compilation problems:
    The import javax.servlet cannot be resolved
    The import javax.servlet cannot be resolved
    ServletContextListener cannot be resolved to a type
    ServletContextEvent cannot be resolved to a type
    ServletContextEvent cannot be resolved to a type

Please understand that in today's multi-layer frameworks, Eclipse interacts with other software. For instance, the message "Unresolved compilation problems" led me at first to believe that Tomcat now added just-in-time compilation to their framework; only afterwards did I discover that Tomcat was running Eclipse's miscompiled code.

Please see JLS, 7.5.1 Single-Type Import Declaration: "a compile-time error occurs if the named type does not exist."  It doesn't say: "a compile-time error occurs, or code hiding the problem may be generated at the discretion of your IDE"
Comment 1 Olivier Thomann CLA 2010-05-20 14:47:10 EDT
Don't you have compile errors ? You can decide not to run code that has compile errors.
Comment 2 Godmar Back CLA 2010-05-20 15:00:28 EDT
> Don't you have compile errors ? You can decide not to run code that has compile
errors.

The compile errors occurred while Eclipse was left unattended, thus I could not "decide not to run code that has compile errors." I expected Eclipse to fail-stop.

Guys, please don't write this off as user error. It's your imposing your personal philosophy on the unexpecting. Make it at least so it can be easily turned off.
Comment 3 Stephan Herrmann CLA 2010-05-20 15:42:38 EDT
(In reply to comment #2)
> > Don't you have compile errors ? You can decide not to run code that has compile
> errors.
> 
> The compile errors occurred while Eclipse was left unattended, thus I could not
> "decide not to run code that has compile errors." I expected Eclipse to
> fail-stop.

What is your setting in
Run/Debug > Launching
 Continue launch if project contains errors
 ( ) Always ( ) Prompt
?
Comment 4 Godmar Back CLA 2010-05-20 15:46:57 EDT
Irrelevant because I don't use Eclipse to launch my project.
Comment 5 Godmar Back CLA 2010-05-20 15:52:20 EDT
(In reply to comment #4)
> Irrelevant because I don't use Eclipse to launch my project.

Plus, not only do I not use Eclipse to launch, I can't even find the option you're referring to.  Under Project Properties, I have Info, Builders, CVS, Java Build Path, Java Code Style, Java Compiler, Javadoc Location, Project References, Refactoring History.

Under the menu item "Run", I have "Run ..." but no configuration created.
Comment 6 Deepak Azad CLA 2010-05-20 15:58:34 EDT
(In reply to comment #5)
> (In reply to comment #4)
> > Irrelevant because I don't use Eclipse to launch my project.
> 
> Plus, not only do I not use Eclipse to launch, I can't even find the option
> you're referring to.  Under Project Properties, I have Info, Builders, CVS,
> Java Build Path, Java Code Style, Java Compiler, Javadoc Location, Project
> References, Refactoring History.
> 
> Under the menu item "Run", I have "Run ..." but no configuration created.

Look under Window-> Preferences

Out of curiosity, how do you launch? and dont you see absence or presence of very prominent red 'x' on projects in eclipse which have compile errors.
Comment 7 Olivier Thomann CLA 2010-05-20 16:53:20 EDT
You could get what you want by using the batch compiler.
This is like that for the last 10 years. This is unlikely to change before 3.6.
I'll investigate what it would take to add the support inside the IDE. The consequence will be many more secondary errors and the inability to run any program that contains minor errors (located in one method only).

Daniel, do you want to investigate a fix for 3.6?
Comment 8 Godmar Back CLA 2010-05-20 16:59:58 EDT
> Out of curiosity, how do you launch? and dont you see absence or presence of
> very prominent red 'x' on projects in eclipse which have compile errors.

To repeat myself, the project was set to "Automated Build" and I did not look at the minimized Eclipse window. The errors were caused because I removed a .jar file (which I did, btw, to avoid a Tomcat warning. Tomcat doesn't allow servlet-api.jar in a WEB-INF/lib directory; it causes a class loader warning because it's against the servlet specification. But that location is where it must be for Eclipse to see it - otherwise, we have an unwanted external reference).

I don't "launch" at all. I recompile straight into the WEB-INF/classes directory and Tomcat runs with Context reloadable set to true. The web application's .class files are automatically reloaded every time new .class files appear. Seems a very efficient and natural solution to me. (For production use, I deploy as .war, but this is during development.)
Comment 9 Stephan Herrmann CLA 2010-05-21 04:45:24 EDT
(In reply to comment #8)
> To repeat myself, the project was set to "Automated Build" and I did not look
> at the minimized Eclipse window.

What do you suggest, how should Eclipse help you if you have it minimized?
Given that you don't expect an "Unresolved compilation problems" error,
what *do* you expect? ClassNotFoundException?
Comment 10 Godmar Back CLA 2010-05-21 05:22:28 EDT
(In reply to comment #9)
> (In reply to comment #8)
> > To repeat myself, the project was set to "Automated Build" and I did not look
> > at the minimized Eclipse window.
> 
> What do you suggest, how should Eclipse help you if you have it minimized?
> Given that you don't expect an "Unresolved compilation problems" error,
> what *do* you expect? ClassNotFoundException?

It's really none of Eclipse's business. I don't expect Eclipse to "help me," I would be happy if it stayed out of the way and didn't sow additional confusion. 

Here's what I would have expected to happen:

$ java ThisClassNeverSuccessfullyCompiled
Exception in thread "main" java.lang.NoClassDefFoundError: ThisClassNeverSuccessfullyCompiled
Caused by: java.lang.ClassNotFoundException: ThisClassNeverSuccessfullyCompiled
        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:307)
        at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:301)
        at java.lang.ClassLoader.loadClass(ClassLoader.java:252)
        at java.lang.ClassLoader.loadClassInternal(ClassLoader.java:320)
Could not find the main class: ThisClassNeverSuccessfullyCompiled.  Program will exit.
Comment 11 Dani Megert CLA 2010-05-21 05:43:38 EDT
>Please see JLS, 7.5.1 Single-Type Import Declaration: "a compile-time error
>occurs if the named type does not exist."  It doesn't say: "a compile-time
>error occurs, or code hiding the problem may be generated at the discretion of
>your IDE"
Mentioning what the spec doesn't say is useless. It does also not say that no class file must be generated if a compile-time error occurs. If you infer something from the behavior of another compiler then that is up to you.

As Olivier said, you can either use the batch compiler, an Ant task that calls that batch compiler or even an Ant task that calls javac.

No time/plans to change the current behavior that exists for 10 years. If this is very important to you then you can provide a patch that adds a preference to disable it. Until then this is a WONTFIX.