I am currently working at a project developing a piece of client/server software. I had a strange problem and hopefully solved it, but I totally can't explain the cause and I searched for a long time.
I wanted to have a while(true) loop on server side to force the server to continue accepting clients, after the one before has closed the socket.
So I tried to build it like this:
public void run() {
Socket socket;
while(true) {
try {
socket = server.accept();
BufferedInputStream in = new BufferedInputStream(socket.getInputStream());
BufferedOutputStream out = new BufferedOutputStream(socket.getOutputStream());
while (socket.isConnected()) {
// TODO income handling
}
in.close();
out.close();
socket.close();
} catch (Exception e) {
break;
}
}
}
But I got an error message by Intellij telling me to add an end condition to this loop. But I have got one in the catch-statement. Changing
while(true)
to
while(!false)
have led the error message to disappear. Can anyone explain me the difference and why the first attempt did not work? I found it done this way multiple times during research.
First of all, the purpose of the IntellJ IDEA inspections is to help you quickly discover problematic code, not to make your life harder.
You definitely should not change your code just to make your IDE happy.
This inspections ("'while' statement cannot complete without throwing an exception") produce warning by default.
So if you really got an error then you probably accidentally changed settings for this inspections.
List of available inspections along with their severity settings can be found in the Settings dialog at Editor > Inspections tab.
Regarding difference between while (true) and while (!false):
Both of them will produce equal byte code so there is no differences, just lack of this intention implementation.
If you don't want to see warnings for particular intention you can:
place text caret on highlighted code (while in this case)
press Alt-Enter
choose in the just opened context menu "Inspection 'Infinite loop statement' options"
And either
disable it for this particular statement (menu item "Suppress for statement")
disable this inspection completely (menu item "Disable inspection")
or open settings dialog (menu item "Edit inspection profile settings").
You're patching your app by doing this.
The IDE(IntelliJ) detects you're doing something you shouldn't and you trying to avoid IntelliJ try to prevent your bad practices by adding something even worse.
Change the condition to something that can finish at some moment or use a flag evaluation.
By the way, declare infinite classes and instances inside an infinite loop is a terrible bad practice.
This is probably because of the way you formatted the while loop condition.
If the expression is complex or convoluted. The compiler does not realize the statements are identical, as T.J. Crowder stated above. Another explanation would be that the while(!false) that you created is not actually while(!false). Show what you changed the while loop to for more clear help from others.
Related
I am using Android Studio IDE (v1.5.1) and its Gradle debugger to step thru my Java application. I can single-step, step-over, step-out, break, set breakpoints etc., but I cannot find a way to manually set the next instruction/statement to be executed or alter the execution flow.
An example of this feature is Visual Studio's "Set next statement" under the DEBUG menu. Another example is MSDOS's g =address where you can specify the next instruction to be executed.
Does the Android Studio Debugger provide a means to change or specify the execution point of the target application?
While this is not possible, I usually workaround in the case of simple blocks of code that I might want (or not) to jump.
First you catch the block in a if statement:
int foo = bar.toFoo();
...
boolean doThis = Boolean.TRUE;
(B) if (doThis) {
...
// stuff that I might want to jump
...
}
Here (B) is a breakpoint. Now when it is reached, I just click Evaluate expression and, if needed, evaluate doThis = false;.
One might argue that a decent compiler should get rid of doThis, but it actually works in Android Studio 1.5, probably thanks to Boolean.TRUE instead of true.
If willing to, Evaluate expression will also let you execute full blocks of code while stuck at the breakpoint.
So I coded up a simple test program for an algorithm in Eclipse 3.7.2. When I went to go run it, I was met with some gray bar that appeared on the top portion of the console. It reads: <terminated> test[Java Application]C:\Program Files\Java\jre6\bin\javaw.exe. Anyone know what's causing this?
Your program is executing properly. The problem is in the logic of your program which is never allowing it to reach the print statement.
When you do
if(s==original)
return;
This statement s==original always returns true in your case since this operator will compare the two objects.
You need to rethink your logic here and google about what == operator does in Java.
Also, on another note, instead of using an array String[] s = {"a","b","c"}, why dont you use a string String s = "abc";
You Need to go to Control Panel > Windows Firewall and select Restore defaults but if you don't want to lose other settings, you could try Advanced Settings and find eclipse in there.
Eclipse is awesome for writing java programs but today I find that it's awesome to trick new coders like me. #_#
I write a snippet as following,
public static void main(String[] args) {
for(int i=0;i<3;i++){
System.out.println("i = " + i);
}
}
then I add a breakpoint at the line of "System.out.print....", click "Debug" button, eclipse goes to the "Debug" perspective and the line of breakpoint is highlighted, then I move the cursor over variable "i", its value is "0" as expected.
And then, I select the "i++" and click "Inspect"(or press "Ctrl+Shift+I") once, I move the cursor over variable "i", its value changed to "1". I repeat "Inspect" again, the value of i changed to "2"......(its value will add by 1 every time I clicked the "Inspect")!!
Why does this happend!? I ONLY want to watch the value of "i" for debug propuse, DO NOT want to really change its value until I step into next statement. I think that "Inspect", as well as "Display" are only for viewing the variable/expression, they should not impact the value, but in this case, it doesn't work as I expect to.
Could anyone tell me what went wrong?
My eclipse version info:
Version: Indigo Service Release 2
Build id: 20120216-1857
If you inspect an expression, eclipse has to execute that expression so you can get the value. Therefore, if you inspect i++, eclipse adds one to i.
Think about it this way: If instead of i++, you inspected myFunction(i), would you expect eclipse to execute the function "myFunction" to get the value? It's the same with i++.
If you are concerned about displaying/showing values while debugging and do you want to be sure not affecting the value, you should select the variable or expression and use the "Watch" option.
This will track the variable/expression value without executing, just updating the new value each time this is run. I think is the most secure way.
As Pablo mentioned, it has to evaluate the code in order to tell you what value it returns. You could instead put a watch on "i+1" and that would give you the value you want without the side effect you don't want.
Basically, you need to be aware of any side effects of anything you launch, whether from the "main" code or from the debugging tools. As Erhannis mentioned, this is very useful at times for modifying values while debugging your code. (For example, you can verify that a tweak/fix is indeed helpful before actually tweaking your code.)
You were expecting "an isolate area" but this would be extremely hard to do, especially in an object-oriented context where many objects are linked to many other objects. Running the whole thing in parallel might sometimes work, but you'd lose the tweaking ability above. And in any context, you'd run into tons of problems with fighting over resources; e.g. both copies trying to read/write a particular file such as a log file. Also, the two execution paths could diverge, leading to incorrect/misleading watch values.
So, preventing such side effects is not really a feasible option here and would rarely be useful anyway. Just expect that the watches can both reflect and affect the code execution.
I've been recently using sonar for code analysis. When I go thorough violation drilldown, I found many java files with if statement defined without braces (thousands of places). Is there a simple way to replace or add braces to if statements or what are the steps that I can perform to achieve this task without doing it manually in each of the files.
I'm currently using intelliJ.
Is there a simple way to replace or add braces to if statements or what are the steps that I can perform to achieve this task without doing it manually in each of the files.
I don't know if there is a tool to do this automatically. (There probably is ...) But assuming that such a tool exists, I'm not convinced it would be the right approach.
Step back for a moment and consider why the code analysis has reported this as a problem. A lot of people (like #pst and me) think that the braces always should be there, even though various style guides don't insist on this. There is a good reason for this ... apart from "it looks ugly". Consider these example code snippets:
if (i == 1)
i++;
doSomething();
while (i < 1)
i++;
doSomething();
If you don't read those carefully, your eyes will trick you into thinking that doSomething(); is called conditionally ... due to the incorrect indentation. And it happens.
(Aside: labelling someone as "inept" for misreading that code is not helpful. If you are desperately trying to fix a show-stopper bug and you've been working for 14 hours straight, then you are likely to miss this kind of thing. And not because you are inept. Once you've been in that situation a couple of times, the lesson sinks in ...)
OK, now suppose that you run an automatic tool to add the braces. What you will get is this:
if (i == 1) {
i++;
}
doSomething();
while (i < 1) {
i++;
}
doSomething();
It means exactly the same thing as the original code. BUT ... what if the original code was actually a bug? What if the programmer intended the doSomething() calls to be conditional?
In short, by adding the braces automatically, we've obscured the original programmer's intention, and made these bug(s) harder to track down.
Bottom line - I think it would be prudent to manually review each of these occurrences ... rather than just "fixing" them automatically. Indeed, I'd argue that if you don't have the time or patience to review them manually, it would be better to leave the code alone. It would be better to turn off the warning ... IMO.
I can reformat the code to make intelliJ do the thing for me, but I need to go through all the files and reformat it. Yes, I might turned off the check but wondering if there is a good tool to do the task. I've good set of tests to check whether it introduce bugs during the process.
If you are sure that you have some ways to test that you will not introduce bugs then use the IntelliJ Reformat Code feature.
Just make sure that the Code Style you have in IntelliJ is in line with your company's policies. Otherwise you will force your style on everybody else too.
To force braces just mark them as Always on the Wrapping and Braces tag in the Code Style settings dialog in IntelliJ.
Mark the source folder in the project view and press Ctrl-Alt-L. A dialog pops up and there you can chose All files in directory <...>.
Then press Run and see what happens. If you are not satisfied then just revert from your VCS.
IntelliJ IDEA has an inspection for this as well, and it has a quick fix to automatically add the braces.
Invoke Analyze | Run Inspection by Name and enter inspection name Control flow statement without braces. Run it on the desired part of your project. In the inspection results you can apply the quick fix Add braces to statement.
Note that this inspection will also report control flow statement other than if, like for example while statements. Invoking the quick fix will also add braces to those statements.
I'm developing a swing application and I'm a bit confused how can I handle exceptions for example lately a part of my code rename files, So when I was testing it I came up with a "you don't have permission to rename file" as I got it from print exception message. So How Could I express this message to user? and should I use JOptionPane message or just show it on the status bar?
Thanks
From your question it sounds like you already know how to handle the exception in the java sense. However you are looking for advice on how to react to exceptions once you have caught them.
In the specific example you give in your question I (as a user) would want that error presented quite clearly so a JOptionPane may be your best bet. I wouldn't just update the status bar as that is very close to silently failing and the user will just be left confused.
A personal rule of thumb is that if the user is likly to be waiting on the code to complete before getting on with their task then they must be informed of the failure strongly i.e. a modal box. If the failure is in a background task that the user can carry on without caring about, or the code can recover from it, or the code is going to retry, then I would go with the more subtle approach of the status bar or icon change depending on the UI.
To elaborate on a comment made by Kevin D - it really depends on your expected user audience. If they are technically proficient you can use the exception text as is. If not then I would prefix the message with "An error has occurred, please contact your technical support personnel with the following information: " then append the error message and ideally a unique identifier for locating an associated log entry... I often use a timestamp for this.
If you really want to get fancy you can email the tech support people with much more detail like the exception and full stack trace, copy of log entry, etc. I have done this in the past but you have to be careful as a frequently occurring error will quickly flood an inbox :)
Of course if the error can be fixed by the user then you can just say so (and how to do so) in your message. That is about as thorough and fancy as you can get...
I don't quite understand the first part of your question, but I try to answer the second one. In general, how you want to display an error to the user depends of the software and error. In most cases JOptionPane or similar is appropriate. However, in some cases a modal dialog might be too intrusive and status bar might be a better way to go. But again, this depends on what kind of software you're writing.
If you anticipate an exception could occur as a result of a user action, then you should explicitly catch it at the point that makes sense and ensure your program recovers correctly.
For example if the user can rename a file, you might invoke a rename() method which returns a status code to indicate success or a failure error code. Inside the method one of these codes might actually be triggered by an exception but the calling code doesn't care. Once the call returns, the status code can be used to determine which error message to show (if any).
enum RenameStatus {
Success,
Failed,
SecurityFailed
}
void doRename(File fromFile, File toFile) {
switch (rename(fromFile, toFile)) {
case Success:
break;
case Failed:
// todo generic dialog rename operation failed
break;
case SecurityFailed:
// todo security dialog rename operation failed due to permission
break;
}
}
RenameStatus rename(File fromFile, File toFile) {
try {
if (!fromFile.renameTo(toFile)) {
return RenameStatus.Failed;
}
return RenameStatus.Success;
}
catch (SecurityException e) {
// Error - permission error
return RenameStatus.SecurityFailed;
}
catch (Exception e) {
return RenameStatus.Failed;
}
}
If you catch the expression (enclosed in a try - catch - block) you get notified when this exception occurs. Then you have to decide: Is there a way to make things work again? Could you, for example, ask the user for another file name? Then do that! But if there is no sensible way of circumventing the error, then just have the program abort.
File permission is kind of a "normal" exception, not a truly "exceptional" one as "disk full" would be, so you'd probably just use JOptionPane instead of sending an error report. That being said, some earlier answers are very informative and should be adopted for the general cases.
In addition, my main() always start with this:
Thread.setDefaultUncaughtExceptionHandler(new UncaughtExceptionHandler()
{
public void uncaughtException(Thread t, Throwable e)
{
// do your things: see earlier answers
}
}
Use Try-Catch handling...
http://tutorials.jenkov.com/java-exception-handling/basic-try-catch-finally.html
When you catch the exception you can do whatever you want with it. Display it to the user, do something else in the code, display another message to the user based on the exception, etc.