Is it possible to enter an infinite loop at compile time?
My program seems to enter an infinite loop when I attempt to compile it. I have a class with a class constructor that calls the method gameRun(). gameRun() calls itself at the end of its execution, but should have the appropriate checks to be able to break from it during run time... However when I attempt to compile the class, I actually seem to get an infinite loop then.
My understanding of compilation is that it does not actually execute the code... Which would mean it would be impossible to enter an infinite loop unless there is actually a serious bug in the compiler's source. Is this correct?
I am writing in Java, and am using BlueJ (a beginner's IDE which I am growing out of) as my IDE.
Thanks in advance.
.....................................
Thanks to you all for so many helpful responses. Just thought I'd post an update, as this seems to have perked some interest, and I am curious about it myself.
I have not done a whole lot with BlueJ or this error since I posted the original error, becuase I had taken the source files from the project, and was able to successfully compile and run them with eclipse. This suggests to me that it is a BlueJ (or related) problem. I have continued to work on this project with eclipse without any more problems of this nature. I will follow up with more detail on the problem when I am able to use the machine with the original project on it again. (Nothing should have been changed since)
.....................................
As an afterthought... Is there any way I can link this question to an account I have created and registered since this was posted? I can't find a way to do that, and it would make keeping track of this more convenient...
Some languages do allow the compiler to enter an infinite loop. Java isn't one of those languages. :-)
You're right, the compiler doesn't execute the code, and would only enter an infinite loop due to a bug. I'm confident that the javac compiler from Sun doesn't have such a bug.
I don't know what compiler BlueJ is using "under the covers", but I have seen a problem when Ant runs javac that makes it take a really long time to compile. Simply stated, there are some cases where Ant will direct the compiler to load every class under a given directory. If that directory contains hundreds of third-party libraries, it can take a while… or even run out of memory.
Does your compilation hang (loop) if you just use javac ?
I've never seen a compilation hang indefinitely whilst compiling Java and I'm wondering if BlueJ is having a problem instead.
It would be theoretically possible to do if, for example, to compile a file, the compiler first had to have finished compiling that file. (Ahhh... Recursion).
But I'd imagine checking for that kind of madness would be the first thing a real-world compiler would handle.
But I wouldn't think it would happen on a method/function, unless (postulating) the compiler was trying to resolve tail-recursion to an simpler implementation, and failing. But, again I can't imagine that would be an issue with a modern Java compiler, even if it exists at all. Certainly I'd imagine that the compiler would eventually give up and post an error rather than infinite looping.
It's far more likely to be the IDE than the compiler. At a guess, the IDE might be trying to trace a warning/error to its source in the code in order to highlight it and getting trapped. Does BlueJ have text-highlighting on compiler errors/warnings? You could try turning it off.
Although, as many others have already suggested, the first real test is to compile from the command line using
javac *.java
Or whatever files your code uses.
EDIT: Sorry I never got back to you. For future reference, to compile from the command line (I'm assuming Windows as your OS):
Open the command line by going to the start menu and select Run...
Type cmd into the Run dialogue, and click OK.
This should bring up a cmd.exe console.
From here, use the "cd" command to change directory to the directory containing your java files.
(cd "My Documents\Java\Monster Battle\core")
Once you're in the right directory, type "javac *.java". This will run the compiler without needing to deal with the IDE. It should pause while compiling, and when it's done, you get the command prompt back.
If you type "javac *.java -verbose" you get full output, in case you get your infinite loop.
If that works fine, it's an IDE bug. Send them a bug report. If it doesn't, congratulations! You've found something really interesting, that will probably tie up some poor Sun developer for a month.
If BlueJ does use its own compiler, you may have found a bug in it, or in BlueJ's build tools that surround it.
You might take a BinaryChop approach to this one: break your program into pieces, compile them individually, and see if the compiler-hanging behavior can be isolated to a small, specific testcase. At the end of the day, you'll either have an excellent bug report to show the BlueJ people, or you'll find that your program actually does compile (yet you'll be scratching your head).
AFAIK, Standard Java cannot be compiled infinitely.
Are you sure that the problem is at compilation rather than at some other feature that BlueJ provides? Many Eclipse-based IDEs perform multiple actions during a rebuild, and that compilation is just one of them. It is possible that something else does.
What exactly do you see? An unending Eclipse task?
Try to make the source code you are compiling as small as possible and still exhibit the behaviour you describe. The process of doing so, may help you identify what the problem is.
Related
Basic background data: Windows 7, Netbeans 8.0.2, LWJGL 2.9.3, Slick Util.
The rest of the code is my own.
So, periodically, I was having what I thought was a bug, that caused my program to run within the IDE, but would fail when I used "Clean and Build" on the project.
Today, when it happened again, I decided to get to the bottom of it. So, taking a copy of the whole project folder, that was working and otherwise identical, and replacing 1 file at a time, and testing it, I was able to narrow it down to the /nbproject/project.properties file.
Every other file could be replaced and the problem persisted. Replace ONLY this file, and the problem went away. So then I loaded up both files and compared them side by side (using the Netbeans "Diff to..." feature) and narrowed it down to the following lines:
javac.classpath=\
${libs.LWJGL-2.9.3.classpath}:\
${libs.0-Slick_Util.classpath}:\
${libs.0-Loaders_v03.classpath}:\
${libs.0-Text2D_v03.classpath}:\
${libs.0-Foundation_v04.classpath}:\
${libs.0-Abstracts_v04.classpath}
Now this code, looks like it is telling the compiler the ORDER in which the libraries should be loaded (I may be wrong).
With that in mind, I decided to test it. I copied this block from the working file, to the non-working file, and it worked just fine. The working code btw is this:
javac.classpath=\
${libs.LWJGL-2.9.3.classpath}:\
${libs.0-Slick_Util.classpath}:\
${libs.0-Foundation_v04.classpath}:\
${libs.0-Abstracts_v04.classpath}:\
${libs.0-Loaders_v03.classpath}:\
${libs.0-Text2D_v03.classpath}
The only differences, you may notice, is the ORDER. Continuing my test, I went into the non-working project's Library properties page, and simply re-ordered the libraries to match the working list. PROBLEM WENT AWAY! If I simply moved the Foundation and Abstracts libraries down in the list, the PROBLEM CAME BACK!
I must have tried a dozen different order combinations, and got about 2/3 that failed, and 1/3 that worked. The ones that worked all involved Foundation and/or Abstracts to be near the top.
Why is this happening? How can I know what order my libraries need to be loaded to avoid the error?
The error btw is this:
F:\Dropbox\2-Documents\4-Java Programming\Library\0-LoadingScreen_v04-Copy\src\A_Library\Test_LoadingScreen.java:94: error: cannot find symbol
Lib_Foundation .setConfigLocation(configLocation);
symbol: method setConfigLocation(String)
location: class Lib_Foundation
Any information that can help me avoid this problem in the future will be appreciated.
It would appear that either “Loaders_v03” or “Text2D_v03” contains its own version of Foundation, including an incompatible Lib_Foundation class. A classpath is searched in order, so your current solution—reordering javac.classpath—will always work, assuming NetBeans doesn’t mess with it the next time you make any change to your project.
Whether that will break Loaders and Text2D depends upon how well Foundation adheres to object-oriented design: public classes and their public members are never supposed to be changed or removed in successive versions. (That is why 20-year-old code written for Java 1.1 will still compile in Java 8.)
So this will be a long story so I thank you in advance for reading. Let me start by saying that I've been working with java for more than 15 years and I've been working on this specific project for over 5 years and I'm stumped.
I compile the project on 3 different computers. I was working on the project in eclipse juno on Computer A and everything was fine so I checked in the code. Then I checked out the code on Computer B and tried a javac clean build and got a bunch of errors, starting with "cyclic inheritance involving..." and then a bunch of errors such as "cannot find symbol" and there were many of these then it had a couple of these "no suitable method found for" until finally it just wigged out and never even gave me an error total.
So, I've never seen anything like this, and as I said the code was fine earlier in the day on a different computer, so I just fired up eclipse, told it to do a clean build, and everything was fine. Go back to the terminal and do a javac and it compiled fine. Whew, I said, it must have just been a glitch.
Then on Computer C, which does a nightly build, it gave the same errors as Computer B (note that Computer B is a mac and Computer C is rhel, but both were running jdk1.7u15). So now I realize it isn't a glitch, but what to do?
I go and look at the code and I'm certain there is no cyclic inheritance and what it says it can't find the symbol for is sitting right where it is supposed to be. I investigate a bit and find out that eclipse uses an internal compiler so this would explain the disparity between compilations, but it doesn't explain why they are giving wildly different results on the same code base.
Out of ideas, and hoping there is something weird with the update 15, I update Computer B to jdk1.7u51 but unfortunately it is giving the same errors.
I realize without seeing the compiler output (which is really not much more interesting than I described), or more importantly, not seeing the actual code there isn't much you can help with. But assuming I'm telling the truth, that there is no cyclic inheritance, there are no missing symbols, and eclipse compiles the code fine when javac rejects it, does anyone have a suggestion of what I could try now?
My next thought is to update eclipse, but assuming it still compiles fine there, what to do next?
Thanks again for reading!
I have been wondering about something lately.It is about the errors which an IDE like netbeans show us while we type the code(Let's assume java).I want to know whether an IDE is capable of identifying all the compile time errors while we type? It means if we run the code with an IDE, are we supposed to get only the run time errors?
If the IDE supports it, it will tell you all the errors in the code, before you even click "Compile". This applies to all IDEs, if I'm not mistaken, some will also give you any errors that the compiler itself returns.
It really all depends on your IDE, settings, and sometimes compiler.
Hope this helps. :)
It means if we run the code with an IDE, are we supposed to get only the run time errors?
It depends on the IDE. For example, in Eclipse, if there are any compile-time errors when you try to run the code, it will warn you about this, but still allow you to continue if you want to. At that point, any code which successfully compiled will execute as normal - but any methods or classes which couldn't be compiled will have the failure represented as an exception thrown by the generated code. Exactly where the exception is thrown depends on the kind of compilation failure.
In general, most of the time you should be running code which compiles without any errors. While the ability of Eclipse to "fake it" is occasionally handy, it would be a bad idea to get into the habit of using it instead of fixing up errors as you go, in my view.
EDIT: If the question is "Will I always know if there are any compile-time errors" then yes, assuming you don't blindly dismiss the warning that Eclipse gives you. I don't know of any IDE which will silently let you run code with compile-time errors in. (You should also look at the Errors view, or whatever your IDE happens to provide, of course.)
It is based on what IDE you are referring to and its settings.
No. EditPlus doesn't show any compile time errors.
Eclipse/Netbeans, based on settings output will be different.
It's quite simple:
If your IDE is capable it will look at what you have written and see if it matches the spec BUT...
Certain times what you write wil be unable to be checked i.e. explicit casting of an object to a Type where you pass in the wrong type i.e. typecastexception.
Somethings CAN be known by a compiler i.e.
int a = "abc"; // obviously wrong because "abc" is a string and not an int(eger) and COMPILE time
Somethings CANNOT be known (EDIT: if you pass a true into findTheRunTimeError you WILL get a RUNTIME error)
int a;
public someFunction(object passedIn, bool findTheRuntimeError)
{
if(!findTheRuntimeError)
{
return;
}
a = (string)passedIn;// obviously wrong cast because passedIn is cast to a string which is not an int(eger) and RUNTIME
}
There is now way for the compiler to know what is going to be passed and cast so therefore it will always be a runtime error.
As you type, your IDE compiles your code after you finished a word or something like that. That way it is able to show you coding mistakes like non-existant variables or other compile time errors.
Your IDE uses your configured Java compiler to do that. When you try to compile incorrect code using javac on the command line it also gives you information on your mistakes. The IDE does the same, parses the information it gets from javac and highlights them in your code.
Even I disabled the "Build Automatically", the realtime syntax checking still works, so seems the "Build Automatically" is useless?
Should I just turn it off?
Build automatically helps you know if there are any compile errors.
Its always a good practice to keep build automatically on as to ensure that you dont checkin any code that causes compile issues
Syntax checking isn't the same as building.
Do you really want to wait for the compilation cycle whenever you want to run your program after small changes? "Automatic build" does this compilation in the background and therefore saves your precious time when launching the application.
If you use maven and you edit some classes during mvn build and autobuild is on, it can break build and leave it in unexpected state (doesn't have to end with error). But i still have it turned on, just not changing code while mvn building.
It is a 'nice to have' feature because it gives you compile errors real-time. People also hate it because they complain it distracts them while they are typing out a lot of code and half way through typing the screen is filled with a bunch of red lines.
But this nice feature comes at the cost of your CPU. If I am on a slower machine or if I have other processes running that are CPU intensive then I turn off the auto-build feature. At that point you have to manually hit the shortcut key to build your code. Honestly you just get used to hitting the shortcut without even thinking after a while.
Currently, I am using Rhino engine to execute some big blocks of javascript code on the server side. However, sometimes, it takes so long(more than 10 minutes) and eat up all CPU usage (at least on my local development env, it is doing this right now).
So I am wondering that what I can do to improve the current system or I can try a new one there.
Any thoughts would be appreciated.
Thanks!
PLUS:
It throws the exception while the code is too big:
java.lang.Exception: No Context associated with current Thread
You can compile the script before running it and cache the compiled version
see http://download.oracle.com/docs/cd/E17409_01/javase/6/docs/api/javax/script/CompiledScript.html
(edit: ops... i don't know if that would work on sdk 1.4)
We first have to know how big are the Javascript blocks that you are executing? 10 lines? 50 lines? 1000 lines?
If its getting 50+, then perhaps compiling would help. Since you are using 1.4, you must be using the official Rhino distribution and not javax.script. In that case just use the rhino compiler.
First though, have you profiled your program? Perhaps its something else thats causing the issue.
Are you sure your algorithm is as efficient as possible?
Please consider these before blaming Rhino
You generate the whole javascript code dynamically from database? maybe you could consider writing a fix piece of code, and filling data into the code with functions like:
ScriptableObject.putProperty(scope, "out", out);
ScriptableObject.putProperty(scope, "script", script);
then you can compile it, and store the 'scope' somewhere and reuse it.
Use the latest release of Rhino, which always has a 'jdk1.4' jar in the release, use it, maybe it'll help.