I have this idea, that anytime an unhandled exception occurs in my JavaFX program, that instead of relying on console output, I can display an alert to the user. I am thinking that perhaps I can capture the output from System.err to use. Here is what I have tried thus far.
PrintStream myStream = new PrintStream(System.err) {
#Override
public void println(String s) {
super.println(s);
Log.debugLog(s); //this function logs to a file and displays an alert to user
}
};
System.setErr(myStream);
This code segment works if I replace System.err with System.out, and System.setErr to System.setOut. However that is capturing System.out, not System.err. I suppose the better question would be, what exact function does System.err call when displaying an error to the console? So that may override it. Any tips are appreciated.
I think you have the wrong approach. If you want to display an alert to the user when there is an unhandled Exception, you can do that by setting a DefaultUncaughtExceptionHandler:
Thread.setDefaultUncaughtExceptionHandler((t, e) -> {
// show alert to user
e.printStackTrace();
// do whatever you want with the Exception e
});
You can create a JavaFX Alert customized to show an exception stack trace along with a brief message. This link shows the code for the below.
Related
I am developing plugin for eclipse. It will run my clang tool. In clang tool i am writing simple pass to check that every case and default statement must have the break statement.
I am running my clang tool using process builder.
I am using job API to run my tool and Display class to print the error.
when i run my plugin i am facing some issue.
Let say i commented my break statement of one of the case or default statement , it should print error in console that every case and default statement must have the break statement.
it is printing error after i type something else or some space or trying to uncomment after my comment .
similarly when i do uncomment , it should not print the error , but it is printing , but again when i type something or some space or trying to comment , error disappear.
following is the link of my code
https://github.com/sunilsarode/eclipse_plugin/blob/master/ccchecker/src/ccchecker/handlers/SampleHandler.java
following image show the first case not printing error on my eclipse console on which i am developing a plugin .
and this shows that second case printing error on my eclipse console on which i am developing a plugin .
any help in this ?
EDIT:
I want my plugin-in to output something on console view (not on development console ) or some dot kind of thing on the gutter of the text editor and when i click or hover on that dot , i want to show some popup with error message.
I tried to print message on console view by crating console using this link https://wiki.eclipse.org/FAQ_How_do_I_write_to_the_console_from_a_plug-in%3F
it works , but new problem is , i lost focus from text editor to console that i have created and because of this i am unable to test the problem i mentioned in question.
sorry too much i am expecting.
Following image show that text editor lost its focus to console view and the button you have mentioned is not there at console view but it is there at console of eclipse on which i am writing a code.
Following keypress method and addKeyListener is not working when i press the Ctrl+s. In order to get the save event we have to use the ICommandService with save command.
((StyledText) editor.getAdapter(Control.class)).addKeyListener(new KeyListener() {
#Override
public void keyPressed(KeyEvent keyEvent) {
if (((keyEvent.stateMask & SWT.CTRL) == SWT.CTRL) && (keyEvent.keyCode == 's')) {
// System.out.println("From Display I am the Key down !!" + keyEvent.keyCode);
Job job = new Job("My job") {
#Override
protected IStatus run(IProgressMonitor arg0) {
// TODO Auto-generated method stub
StringBuilder builder = runCCChecker(path);
syncWithUi(builder);
return Status.OK_STATUS;
}
};
job.setUser(true);
job.schedule();
}
}
#Override
public void keyReleased(KeyEvent arg0) {
}
});
In order to show the warning at each line I am using IMarker interface.
In order to run my tool only on current active file of eclipse editor on which I am firing save command , I am using IPartService service.
following is the link of my code
https://github.com/sunilsarode/eclipse_plugin/blob/master/ccchecker/src/ccchecker/handlers/SampleHandler.java
It is working fine. If anybody find any issue please let me know.
Such a piece of code:
private void log(String message) {
LogBox.append(message + "\n");
}
private void log(Exception e) {
log(e.getMessage());
}
private void ConvertButtonActionPerformed(java.awt.event.ActionEvent evt) {
String url = UrlBox.getText();
if (url.isEmpty()) {
log("Empty URL");
return;
}
LogBox.setText("");
try {
log("URL "+url+" accepted. Trying to download...");
String content = URLConnectionReader.getText(url);
log("Downloaded. Parsing the content...");
//
} catch (Exception e) {
log(e);
}
}
should output each message to the LogBox (JTextArea) immediately after each log call, but outputs URL ... accepted only when URLConnectionReader.getText(url) finishes.
There were several ways do do an immediate output:
Application.DoEvents in Visual Basic 6 and .NET
Application.ProcessMessages in Delphi
Is there some simple way to do an immediate output? I was studying questions about the DoEvents and how to do this in Java, but I think that starting to learn Java from multi-threading isn't a right approach.
Create a SwingWorker to do the download: http://docs.oracle.com/javase/tutorial/uiswing/concurrency/worker.html
The role of an ActionListener is just that: to listen for user action, and initiate a response to that action by the program.
Sometimes, the program's response is very quick, and only involves the GUI. For example, in a calculator app, you could have a listener attached to an "equals" button that calculates the result of the current expression and writes it to a textbox. This can all be done within the listener method (although you might want to separate behavior for testing).
If the response to an user action is to initiate some long-running process, like downloading and parsing the file, then you don't want to do this within the listener body, because it will freeze the UI. Instead, gather any information (in your case, the URL value) from within the listener, and spin up a SwingWorker to handle the program's response.
In my comment, I suggested moving everything after the getText() into a SwingWorker. This is because, to me, the response is "download a file if you have a valid URL, and log the progress." And as I see it, testing for an empty string is part of that response. If you want to leave the empty-string test inside the listener, that's fine, but imo it's less testable.
You must leave the call to getText() inside the body of the listener, because you are only allowed to access Swing components from the event dispatch thread. If you moved that call into the worker, then it might access the textbox at the same time the textbox is updating itself, resulting in corrupt data.
Read up on Concurrency.
You should probably use a SwingWorker for the long running task, then you can publish results to the GUI as they become available.
A similar question was asked here for two times and never there was any answer. Or the answer was: "it is impossible!" Sorry, it is possible too much:
try{
...
// the line that causes the error
LinearLayout cell = (LinearLayout) inflater.inflate(R.layout.channels_list_cell, column);
...
}
catch(Throwable e){
Toast.makeText(this, e.toString(), Toast.LENGTH_LONG).show(); < breakpoint here!
}
At the breakpoint e is null. How can I seek for the error, please? Very possibly it is not the problem of java or Android, but of the Eclipse debugger, that itself needs debugging badly. But what have I to do, except changing to a different IDE? Any ideas? Beforehand grateful.
I have tried Throwable, Exception, RuntimeException. The result is the same.
An attempt to step over breakpoint causes NullPointerException, so, e seems really null at that moment already. Where could it be lost?
Edit:
I bring my gratitude to everybody and +1 to every answerer. It was an Eclipse bug. After restart Eclipse the Exception is not null anymore, it is a normal RuntimeException: Binary XML file line #15: You must supply a layout_width attribute. It would be another problem to be solved, but that one is solved.
If the exception you caught was a NullPointerException, the getMessage() method returns "null" which may be confusing. I know that this has sometimes confused me!
In the debugger, you should be able to select e and see a type and its fields. Also, another way to debug when things get really confusing is to go
e.printStackTrace();
(note - I'm not an Android guru so if this works differently on Android somebody please comment!)
Have you verified whether e is actually null or not? I.e. by adding something like if (e == null) Log.d("Exception is null"). I would then check if the log statement gets triggered both during normal execution and while debugging. If the results are different between the two, it would indicate a VM bug (unlikely, but possible). If the message doesn't get triggered in either case, then it's likely a debugger issue.
A few thoughts on further things you can try to debug the issue:
Try something like jdb and see if you get the same behaviour
You could get a dump of the jdwp communications between the debugger and the device, and see what's going on at that level. Maybe use wireshark or tcpdump and grab the data going over the usb bus to the device.
You could try adding some debug statements to dalvik itself. E.g. grab a copy of AOSP and build an emulator image, and then add some debugging statements to dalvik to try and track down what's going on.
You could attempt to do some sort of scripted jdwp session with the device
You could look at the bytecode (baksmali/dexdump/dedexer), to see if anything looks funny
Android does not always throws exception in a Throwable. It actually drives all the exceptions to the catLog. There you will find details of your exceptions even if in the catch block your exception is null.
You can easily access the catlog console from eclipse and filter to view the errors only
UPDATE:
Your breakpoint should be inside the catch block
I know this question was posted a while ago, and many times too! I fell into this trap yesterday and I thought I'll post what I found.
Problem definition: I used the following code
public class myAppActivity extends Activity
{
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
try { -- lots of code -- }
catch (Exception ex) {
Log.e ("eTutorPrism Error", "Caught this exception " + ex);
ex.printStackTrace();
}
}
}
Symptom was that 'ex' was always null and resume will give NullPointerException, although the actual exception was an IllegalArgumentException in a call made into another class from the code above.
ISSUE: onCreate() code does not display the exception caught. instead it shows exception = null.
Solution: do NOT use too much processing in onCreate(). Move as much as possible to another thread. So I changed the code to look like the following. voila, it works!!! I can see the actual exception displayed in the Logcat.
public class eTutorPrismAppActivity extends Activity
{
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
eTutorPrismTest myTest = new eTutorPrismTest (getApplicationContext());
myTest.start();
}
}
class eTutorPrismTest extends Thread
{
private Context m_AppContext = null;
public eTutorPrismTest (Context appContext)
{
m_AppContext = appContext;
}
public void run ()
{
-- lots of code that needs appContext --
}
}
I am unsure of what causes this -- it could be an Eclipse bug as stated earlier. Regardless of the cause, I did find a workaround that seems to work. I hope it is useful to others as well.
After the exception is caught, assign it to another variable. The assigned variable should contain the correct Exception in the debugger.
SpecificException assignedVar = null;
try {
...
}
catch (SpecificException exc) {
assignedVar = exc; // <-- exc comes up null in the debugger, but assignedVar will be the correct object.
}
Hope this works for others as a workaround.
How do I pop up message in window from java console application?If I use JOptionPane, then I need to pass component which is visible.But if I want to show some warning or error from console application(which does not have any window visible), Then I cant use JOptionPane. Also I want the displayed message to be shown on top of any other application(To get the attention of user ).
Thanks in advance.
You can use
JOptionPane.showMessageDialog(null, "Message goes here");
EDIT:
I tried
import javax.swing.JOptionPane;
public class Foo{
public static void main(String a[])
{
JOptionPane.showMessageDialog(null, "Message goes here");
}
}
and the output was
so your problem could be somewhere else?
If you really need a popup, make the component argument null and it will not have a parent.
I want to print something in console, so that I can debug it. But for some reason, nothing prints in my Android application.
How do I debug then?
public class HelloWebview extends Activity {
WebView webview;
private static final String LOG_TAG = "WebViewDemo";
private class HelloWebViewClient extends WebViewClient {
#Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
view.loadUrl(url);
return true;
}
}
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
webview = (WebView) findViewById(R.id.webview);
webview.setWebViewClient(new HelloWebViewClient());
webview.getSettings().setJavaScriptEnabled(true);
webview.setWebChromeClient(new MyWebChromeClient());
webview.loadUrl("http://example.com/");
System.out.println("I am here");
}
Correction:
On the emulator and most devices System.out.println gets redirected to LogCat and printed using Log.i(). This may not be true on very old or custom Android versions.
Original:
There is no console to send the messages to so the System.out.println messages get lost. In the same way this happens when you run a "traditional" Java application with javaw.
Instead, you can use the Android Log class:
Log.d("MyApp","I am here");
You can then view the log either in the Logcat view in Eclipse, or by running the following command:
adb logcat
It's good to get in to the habit of looking at logcat output as that is also where the Stack Traces of any uncaught Exceptions are displayed.
The first Entry to every logging call is the log tag which identifies the source of the log message. This is helpful as you can filter the output of the log to show just your messages. To make sure that you're consistent with your log tag it's probably best to define it once as a static final String somewhere.
Log.d(MyActivity.LOG_TAG,"Application started");
There are five one-letter methods in Log corresponding to the following levels:
e() - Error
w() - Warning
i() - Information
d() - Debug
v() - Verbose
wtf() - What a Terrible Failure
The documentation says the following about the levels:
Verbose should never be compiled into an application except during development. Debug logs are compiled in but stripped at runtime. Error, warning and info logs are always kept.
Use the Log class. Output visible with LogCat
Yes it does. If you're using the emulator, it will show in the Logcat view under the System.out tag. Write something and try it in your emulator.
Of course, to see the result in logcat, you should set the Log level at least to "Info" (Log level in logcat); otherwise, as it happened to me, you won't see your output.
if you really need System.out.println to work(eg. it's called from third party library). you can simply use reflection to change out field in System.class:
try{
Field outField = System.class.getDeclaredField("out");
Field modifiersField = Field.class.getDeclaredField("accessFlags");
modifiersField.setAccessible(true);
modifiersField.set(outField, outField.getModifiers() & ~Modifier.FINAL);
outField.setAccessible(true);
outField.set(null, new PrintStream(new RedirectLogOutputStream());
}catch(NoSuchFieldException e){
e.printStackTrace();
}catch(IllegalAccessException e){
e.printStackTrace();
}
RedirectLogOutputStream class:
public class RedirectLogOutputStream extends OutputStream{
private String mCache;
#Override
public void write(int b) throws IOException{
if(mCache == null) mCache = "";
if(((char) b) == '\n'){
Log.i("redirect from system.out", mCache);
mCache = "";
}else{
mCache += (char) b;
}
}
}
it is not displayed in your application... it is under your emulator's logcat
System.out.println("...") is displayed on the Android Monitor in Android Studio
There is no place on your phone that you can read the System.out.println();
Instead, if you want to see the result of something either look at your logcat/console window or make a Toast or a Snackbar (if you're on a newer device) appear on the device's screen with the message :)
That's what i do when i have to check for example where it goes in a switch case code! Have fun coding! :)
I'll leave this for further visitors as for me it was something about the main thread being unable to System.out.println.
public class LogUtil {
private static String log = "";
private static boolean started = false;
public static void print(String s) {
//Start the thread unless it's already running
if(!started) {
start();
}
//Append a String to the log
log += s;
}
public static void println(String s) {
//Start the thread unless it's already running
if(!started) {
start();
}
//Append a String to the log with a newline.
//NOTE: Change to print(s + "\n") if you don't want it to trim the last newline.
log += (s.endsWith("\n") )? s : (s + "\n");
}
private static void start() {
//Creates a new Thread responsible for showing the logs.
Thread thread = new Thread(new Runnable() {
#Override
public void run() {
while(true) {
//Execute 100 times per second to save CPU cycles.
try {
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
//If the log variable has any contents...
if(!log.isEmpty()) {
//...print it and clear the log variable for new data.
System.out.print(log);
log = "";
}
}
}
});
thread.start();
started = true;
}
}
Usage: LogUtil.println("This is a string");
I dont having fancy IDE to use LogCat as I use a mobile IDE.
I had to use various other methods and I have the classes and utilties for you to use if you need.
class jav.android.Msg. Has a collection of static methods.
A: methods for printing android TOASTS.
B: methods for popping up a dialog box.
Each method requires a valid Context. You can set the default context.
A more ambitious way, An Android Console. You instantiate a handle to the console in your app, which fires up the console(if it is installed), and you can write to the console. I recently updated the console to implement reading input from the console. Which doesnt return until the input is recieved, like a regular console.
A: Download and install Android Console( get it from me)
B: A java file is shipped with it(jav.android.console.IConsole). Place it at the appropriate directory. It contains the methods to operate Android Console.
C: Call the constructor which completes the initialization.
D: read<*> and write the console.
There is still work to do. Namely, since OnServiceConnected is not called immediately, You cannot use IConsole in the same function you instantiated it.
Before creating Android Console, I created Console Dialog, which was a dialog operating in the same app to resemble a console. Pro: no need to wait on OnServiceConnected to use it. Con: When app crashes, you dont get the message that crashed the app.
Since Android Console is a seperate app in a seperate process, if your app crashes, you definately get to see the error. Furthermore IConsole sets an uncaught exception handler in your app incase you are not keen in exception handling. It pretty much prints the stack traces and exception messages to Android Console. Finally, if Android Console crashes, it sends its stacktrace and exceptions to you and you can choose an app to read it. Actually, AndroidConsole is not required to crash.
Edit Extras
I noticed that my while APK Builder has no LogCat; AIDE does. Then I realized a pro of using my Android Console anyhow.
Android Console is design to take up only a portion of the screen, so you can see both your app, and data emitted from your app to the console. This is not possible with AIDE. So I I want to touch the screen and see coordinates, Android Console makes this easy.
Android Console is designed to pop up when you write to it.
Android Console will hide when you backpress.
Solution that worked for me:
Under Logcat. (To show Logcat if not already shown. Click View menu-->Tool Windows-->Logcat). It is shown as System.out not as System.out.println as you might expect it. Rebuild the app if you have not already.
In the picture, highlighted yellow shows the System.out and output "Hello again".
Recently I noticed the same issue in Android Studio 3.3. I closed the other Android studio projects and Logcat started working. The accepted answer above is not logical at all.