Java - System.setOut does not save an exception message - java

It seems that System.setOut() does not work in this test case.
Here are problem description.
test0 executes System.setOut(new PrintStream(byteBuffer)) so that it stores standard output.
test0 invokes AddChild1_wy_v1.main.
In the AddChild1_wy_v1.main, xml.addChild(null) generates an exception message.
The exception message should be stored in byteBuffer, but it seems it wasn't.. JVM stops running the test case once the exception message pops up. And the remaining code after AddChild1_wy_v1.main are not executed.
Is there a way for jvm to execute the remaining code in test0?
NanoAddChild1_wy_v1Tests.java
package tests;
import junit.framework.TestCase;
import java.io.ByteArrayOutputStream;
import java.io.PrintStream;
import net.n3.nanoxml.*;
public class NanoAddChild1_wy_v1Tests extends TestCase {
public void test0() throws Exception { //addchild1.out
String result;
ByteArrayOutputStream byteBuffer;
byteBuffer = new ByteArrayOutputStream();
System.setOut(new PrintStream(byteBuffer));
AddChild1_wy_v1.main(new String[] {"/home/junghyun/Dev/nanoxml/inputs/simple.xml"});
result = new String(byteBuffer.toByteArray());
assertEquals(result, "Exception in thread \"main\" java.lang.IllegalArgumentException: child must not be null\n\tat net.n3.nanoxml.XMLElement.addChild(XMLElement.java:165)\n\tat AddChild1_wy_v1.main(AddChild1_wy_v1.java:47)\n");
}
}
AddChild1_wy_v1.java
package tests;
import net.n3.nanoxml.IXMLParser;
import net.n3.nanoxml.IXMLReader;
import net.n3.nanoxml.StdXMLReader;
import net.n3.nanoxml.XMLElement;
import net.n3.nanoxml.XMLParserFactory;
import net.n3.nanoxml.XMLWriter;
public class AddChild1_wy_v1
{
public static void main(String args[])
throws Exception
{
if (args.length == 0) {
System.err.println("Usage: java DumpXML file.xml");
Runtime.getRuntime().exit(1);
}
IXMLParser parser = XMLParserFactory.createDefaultXMLParser();
IXMLReader reader = StdXMLReader.fileReader(args[0]);
parser.setReader(reader);
XMLElement xml = (XMLElement) parser.parse();
xml.addChild (null);
(new XMLWriter(System.out)).write(xml);
}
}

There's 3 default streams:
System.in : InputStream
System.out :PrintStream
System.err :PrintStream
So to set each one there is 3 methods:
public static void setIn(InputStream in) {...}
public static void setOut(PrintStream out) {...}
public static void setErr(PrintStream err) {...}
To set System.err you must use System.setErr(yourStream);
For another question: you just need to use
try {
//throwing exception
} catch (Exception e) {
//act on exception
}

It seems to me that you never write that Exception at all.
You just throw it upwards. Try catch it and have ex.printStackTrace();
Also that will go to standard error, unless you specifically say otherwise.
As by your request I will leave the test0 method unaltered, you can use it the way it is.
in AddChild1_wy_v1.java:
public class AddChild1_wy_v1 {
public static void main(String args[]) // note that I don't throw the Exception.
{
try {
if (args.length == 0) {
System.err.println("Usage: java DumpXML file.xml");
Runtime.getRuntime().exit(1);
}
IXMLParser parser = XMLParserFactory.createDefaultXMLParser();
IXMLReader reader = StdXMLReader.fileReader(args[0]);
parser.setReader(reader);
XMLElement xml = (XMLElement) parser.parse();
xml.addChild (null);
(new XMLWriter(System.out)).write(xml);
} catch (Exception any) {
any.printStackTrace(System.out); // note that I send the Stack Trace to standard out here.
}
}
}

Wrap your method call in a try-catch to continue past the exception:
try {
AddChild1_wy_v1.main(...);
} catch(Throwable t) {
t.printStackTrace();
}
// the rest of your code will execute
Exceptions are printed to standard error, not standard output. Try System.setErr.
Never post images of your code.

Related

Exception in thread "main" java.io.IOException: No source has been specified

I'm using Java to create a program that takes in a CSV file and outputs an Arff file. Whenever the program runs it comes up catching the exception that No source has been specified. When I delete the try catch it comes with the following error and I am not sure why,
Exception in thread "main" java.io.IOException: No source has been specified
at weka.core.converters.CSVLoader.getDataSet(CSVLoader.java:867)
at CSVtoArff.Convert(CSVtoArff.java:10)
at CSVtoArff.main(CSVtoArff.java:23)
Below is the code for the program
import weka.core.Instances;
import weka.core.converters.CSVLoader;
import weka.core.converters.ArffSaver;
import java.io.File;
public class CSVtoArff {
public static void Convert(String input, String output) throws Exception {
try {
CSVLoader load = new CSVLoader();
load.setSource(new File(input));
Instances data = load.getDataSet();
ArffSaver save = new ArffSaver();
save.setInstances(data);
save.setFile(new File(output));
save.writeBatch();
System.out.println("File successfully converted");
}
catch (Exception e) {
System.out.println("Does not meet arff standards: " + e.getMessage());
}
}
public static void main(String[] args) throws Exception{
String input = "C:\\Users\\jason\\Desktop\\example.csv";
String output =" C:\\Users\\jason\\Desktop\\example.arff";
Convert(input, output);
}
}
Please try putting the files in C:\temp folder and change it to below and try.
Sometime windows security my be denying access to protected system folders.
Also there is an extra leading space in output file path. I have removed that.
public static void main(String[] args) throws Exception{
String input = "C:/temp/example.csv";
String output ="C:/temp/example.arff";
Convert(input, output);
}

try/catch not working in Java?

I am making an app for android in Qt. So in order to use the Google API I need to implement Java. So I have looked through the QtNotifier example and I am trying to implement the same as a starter.
This Java example comes from the QtNotifier example aswell so it should work the same but it doesn't. I have tried to debug it using the Qt debugger but the breakpoints do not seem to trigger So I added println statements to see at which line it goes wrong. But this is not enough so I am trying to print a stacktrace using a catch/try clause.
I have implemented it like this:
package org.qtproject.qt5.example;
import android.app.Notification;
import android.app.NotificationManager;
import android.content.Context;
import java.lang.Object;
import java.io.Writer;
import java.io.StringWriter;
import java.io.PrintWriter;
public class NotificationClient extends org.qtproject.qt5.android.bindings.QtActivity
{
private static NotificationManager m_notificationManager;
private static Notification.Builder m_builder;
private static NotificationClient m_instance;
public NotificationClient()
{
System.out.println("it works2222");
m_instance = this;
}
public static void notify(String s)
{
System.out.println(s);
try {
if (m_notificationManager == null) {
System.out.println("1111");
m_notificationManager = (NotificationManager)m_instance.getSystemService(Context.NOTIFICATION_SERVICE);
System.out.println("2222");
m_builder = new Notification.Builder(m_instance);
System.out.println("3333");
m_builder.setContentTitle("A message from Qt!");
System.out.println("4444");
}
System.out.println("5555");
m_builder.setContentText(s);
System.out.println("6666");
m_notificationManager.notify(1, m_builder.build());
System.out.println("7777");
} catch(Exception e) {
StringWriter writer = new StringWriter();
PrintWriter pw = new PrintWriter(writer);
e.printStackTrace(pw);
String errorDetail = writer.toString();
}
}
}
The output is:
I/System.out( 4768): test string
I/System.out( 4768): 1111
It would seem that m_instance is still null because "System.out.println("it works2222");" does not get called. But the error does not get caught.
Is it because this is an error that is not an exception?
I have also tried running the QtNotifier app but the printstatement inside.
public NotificationClient()
{
System.out.println("it works2222");
m_instance = this;
}
But that is also not called in the QtNotifier app.
My question is: How can I trace this error?
In Java, there are both Errors and Exceptions. Normally, an Error is significant enough that your program should just crash and exit. However, for debugging purposes, if you want to catch both you should
catch (Throwable t)
{
t.printStackTrace();
}
to get information on both.

Unhandled exception type IOEsxception using ApacheCommnonsIO's method

I am trying to use copyDirectory() method from ApacheCommnonsIO package.
My code is:
First Class
import java.io.*;
import org.apache.commons.io.FileUtils;
public class ClassN1{
public static methodThatUsesCPDIRMethod(){
String src = "/home/user/dir_src";
String dst = "/home/user/dir_dst";
try {
FileUtils.copyDirectory(new File(src), new File(dst));
} catch (IOException e){ }
}
Second class
public class ClassN2{
public ClassN2(){
ClassN1.methodThatUsesCPDIRMethod();
}
}
Main method
public class Main{
public static void main(String[] args){
ClassN2 obj = new ClassN2();
}
}
Is just an example, in code I haven't syntax errors, that can be there.
Problem: the ClassN1.methodThatUsesCPDIRMethod() in second's class constructor is highlighted with an error:
Unhandled exception type IOEsxception
I use VIM + Eclim plugin (Eclipse)
I did not check this, but it looks like the FileUtils are throwing this IOEsxception (interesting spelling!?) which your class don't catch. In this case you have to either add this exception to the method (the c'tor in your case) or you change the catch statement to catch the exception too.
try {
FileUtils.copyDirectory(new File(src), new File(dst));
} catch (Exception e){ //Please log at least a message here!!! }

Redirect console output to string in Java

I have one method whose return type is void and it prints directly on console.
However I need that output in a String so that I can work on it.
As I can't make any changes to the method with return type void I have to redirect that output to a String.
How can I redirect it in Java?
If the function is printing to System.out, you can capture that output by using the System.setOut method to change System.out to go to a PrintStream provided by you. If you create a PrintStream connected to a ByteArrayOutputStream, then you can capture the output as a String.
Example:
// Create a stream to hold the output
ByteArrayOutputStream baos = new ByteArrayOutputStream();
PrintStream ps = new PrintStream(baos);
// IMPORTANT: Save the old System.out!
PrintStream old = System.out;
// Tell Java to use your special stream
System.setOut(ps);
// Print some output: goes to your special stream
System.out.println("Foofoofoo!");
// Put things back
System.out.flush();
System.setOut(old);
// Show what happened
System.out.println("Here: " + baos.toString());
This program prints just one line:
Here: Foofoofoo!
Here is a utility Class named ConsoleOutputCapturer. It allows the output to go to the existing console however behind the scene keeps capturing the output text. You can control what to capture with the start/stop methods. In other words call start to start capturing the console output and once you are done capturing you can call the stop method which returns a String value holding the console output for the time window between start-stop calls. This class is not thread-safe though.
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.io.PrintStream;
import java.util.Arrays;
import java.util.List;
public class ConsoleOutputCapturer {
private ByteArrayOutputStream baos;
private PrintStream previous;
private boolean capturing;
public void start() {
if (capturing) {
return;
}
capturing = true;
previous = System.out;
baos = new ByteArrayOutputStream();
OutputStream outputStreamCombiner =
new OutputStreamCombiner(Arrays.asList(previous, baos));
PrintStream custom = new PrintStream(outputStreamCombiner);
System.setOut(custom);
}
public String stop() {
if (!capturing) {
return "";
}
System.setOut(previous);
String capturedValue = baos.toString();
baos = null;
previous = null;
capturing = false;
return capturedValue;
}
private static class OutputStreamCombiner extends OutputStream {
private List<OutputStream> outputStreams;
public OutputStreamCombiner(List<OutputStream> outputStreams) {
this.outputStreams = outputStreams;
}
public void write(int b) throws IOException {
for (OutputStream os : outputStreams) {
os.write(b);
}
}
public void flush() throws IOException {
for (OutputStream os : outputStreams) {
os.flush();
}
}
public void close() throws IOException {
for (OutputStream os : outputStreams) {
os.close();
}
}
}
}
Although this question is very old and has already very good answers I want to provide an alternative. I created a library specifically for this use case. It is called Console Captor and you can add it with the following snippet:
<dependency>
<groupId>io.github.hakky54</groupId>
<artifactId>consolecaptor</artifactId>
<version>1.0.0</version>
<scope>test</scope>
</dependency>
Example class
public class FooService {
public void sayHello() {
System.out.println("Keyboard not responding. Press any key to continue...");
System.err.println("Congratulations, you are pregnant!");
}
}
Unit test
import static org.assertj.core.api.Assertions.assertThat;
import nl.altindag.console.ConsoleCaptor;
import org.junit.jupiter.api.Test;
public class FooServiceTest {
#Test
public void captureStandardAndErrorOutput() {
ConsoleCaptor consoleCaptor = new ConsoleCaptor();
FooService fooService = new FooService();
fooService.sayHello();
assertThat(consoleCaptor.getStandardOutput()).contains("Keyboard not responding. Press any key to continue...");
assertThat(consoleCaptor.getErrorOutput()).contains("Congratulations, you are pregnant!");
consoleCaptor.close();
}
}
If you are using Spring Framework, there is a really easy way to do this with OutputCaptureExtension:
#ExtendWith(OutputCaptureExtension.class)
class MyTest {
#Test
void test(CapturedOutput output) {
System.out.println("ok");
assertThat(output).contains("ok");
System.err.println("error");
}
#AfterEach
void after(CapturedOutput output) {
assertThat(output.getOut()).contains("ok");
assertThat(output.getErr()).contains("error");
}
}

unreported exception java.io.FileNotFoundException; must be caught or declared to be thrown [duplicate]

This question already has an answer here:
What does "error: unreported exception <XXX>; must be caught or declared to be thrown" mean and how do I fix it?
(1 answer)
Closed 8 months ago.
I am creating a class -- just a class, no main() and I am receiving the error of "unreported exception java.io.FileNotFoundException; must be caught or declared to be thrown" at this line:
FileOutputStream outStr = new FileOutputStream(FILE, true);
I don't understand; I put in a try{} catch{} block and it's still reporting the error.
Additionally, it's also reporting an "illegal start of type" for the try and both catch lines, and it's also saying that ';' is expected for both catch lines.
I'm using the NetBean IDE, FYI.
Thank you for any help.
Here is the full code:
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.PrintStream;
import java.io.FileNotFoundException;
public class UseLoggingOutputStream
{
String FILE = "c:\\system.txt";
try
{
FileOutputStream outStr = new FileOutputStream(FILE, true);
}
catch(FileNotFoundException fnfe)
{
System.out.println(fnfe.getMessage());
}
catch(IOException ioe)
{
System.out.println(ioe.getMessage());
}
}
You need to put the file processing statements inside a method:
import java.io.FileOutputStream;
import java.io.FileNotFoundException;
public class UseLoggingOutputStream {
public void myMethod() {
String file = "c:\\system.txt";
try {
FileOutputStream outStr = new FileOutputStream(file, true);
} catch(FileNotFoundException fnfe) {
System.out.println(fnfe.getMessage());
}
}
}
All functional code needs to go into methods - I don't see a method in your code - that's the illegal start of type problem. The other compile errors should become clearer once you get the basics down.
public class Foo {
public void doSomething() {
//code here
}
}
Move this code to some method or at least to a static initializer block.
import java.io.*;
import java.util.*;
public class SortNames {
private String[] strings = new String[10];
private int counter;
public SortNames() {
ArrayList<String> names = new ArrayList<String>();
Scanner scan = null;
File f = null;
try{
f = new File("names.txt");
scan = new Scanner(f);
while(scan.hasNext()) names.add(scan.next());
}
finally{scan.close();}
Collections.sort(names);
for(String s:names) System.out.println(s);
}
}
Sorry if this isn't helpful to you, but I was able to solve this exact issue by adding " throws FileNotFoundException " to my method call that contained the FileWriter. I know this may not be helpful since you aren't using methods, but then again, maybe it is.

Categories

Resources