2

I've looked all over SO and have yet to find a solution to this. Long and short of it is I'm trying to take a text file from a provided URL and read it into a String so I can do other things with it.

The specific compile error is:

/tmp/java_kWWEO5/Main.java:49: error: unreported exception IOException; must be caught or declared to be thrown
        String text = readUrlTextContent("http://textfiles.com/stories/antcrick.txt");
                                        ^
1 error

The code causing the error, in main:

import java.util.*;
import java.net.URL;
import java.net.MalformedURLException;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.IOException;

public class Main {

    private static String readUrlTextContent(String url) throws IOException, MalformedURLException {

        URL source = new URL(url);
        BufferedReader reader = new BufferedReader(new InputStreamReader(source.openStream()));
        try {
            StringBuilder builder = new StringBuilder();
            String line = reader.readLine();

            while (line != null) {
                builder.append(line);
                builder.append("\n");
                line = reader.readLine();
            }
            return builder.toString();
        } catch (MalformedURLException urlEx) {
            urlEx.printStackTrace();
            throw new RuntimeException("Malformed URL Exception", urlEx);            
        } catch (IOException ioEx) {
            ioEx.printStackTrace();
            throw new RuntimeException("IO Exception", ioEx);
        } finally {
            reader.close();
        }
    }

    public static void main(String[] args) {

        String text = readUrlTextContent("http://textfiles.com/stories/antcrick.txt");
        System.out.println(text);
    }
}

What could I do to modify this short program so that it finally compiles and executes?

Phrancis
  • 2,222
  • 2
  • 27
  • 40
  • possible duplicate of [Does Java declare "throws Exception" by default?](http://stackoverflow.com/questions/30165811/does-java-declare-throws-exception-by-default) – Vogel612 Jul 16 '15 at 22:14
  • you can also do `public static void main(String[] args) throws IOException` – eckes Jul 16 '15 at 22:44

2 Answers2

2

While you actually handle these exceptions in the body of your method by wrapping them into a RuntimeException, your method signature "lies" to the compiler:

private static String readUrlTextContent(String url) throws IOException, MalformedURLException {

Change this line to:

private static String readUrlTextContent(String url) {

That should resolve the compiler message


The problem you're experiencing here is that inherent to checked exceptions. When a method declares it throws a certain exception-type, the compiler is required to check these exceptions are handled.

This means, even though you correctly catch the exceptions in your method body, the compiler must assume, these exceptions can happen.

Accordingly whenever reaadUrlTextContent is called, the compiler checks "Does the caller handle these exceptions?"

If the caller doesn't... well that's what you get :)

What makes your case a little more interesting is that MalformedURLException is a subclass of IOException. This means whenever you catch (or throw) IOException, a MalformedURLException will be handled in the same way, given it has not been already caught.

Vogel612
  • 5,620
  • 5
  • 48
  • 73
  • We cannot change the signature of readUrlTextContent() and remove throws IOException, MalformedURLException w/o making appropriate changes in its definition as I have done above. – Rahul Prasad Jul 16 '15 at 22:25
  • @user403348255 you're talking about the "source.openStream()" line, right? If that's the case: mini-codereview - using a try-with-resources block will eliminate the necessity to initialize the BufferedReader with null – Vogel612 Jul 16 '15 at 22:26
1

Update the signature of readUrlTextContent(String url) as follows:

private static String readUrlTextContent(String url) throws IOException{
}

And, modify main() as following:

public static void main(String[] args) {
    String text = null;
    try {
        text = readUrlTextContent("http://textfiles.com/stories/antcrick.txt");
    } catch (IOException e) {
        e.printStackTrace();
    }
    System.out.println(text);
}

Or only modify readUrlTextContent() as follows:

private static String readUrlTextContent(String url) {
        BufferedReader reader = null;
        try {
            URL source = new URL(url);


            reader = new BufferedReader(new InputStreamReader(
                    source.openStream()));

            StringBuilder builder = new StringBuilder();
            String line = reader.readLine();

            while (line != null) {
                builder.append(line);
                builder.append("\n");
                line = reader.readLine();
            }
            return builder.toString();
        } catch (MalformedURLException urlEx) {
            urlEx.printStackTrace();
            throw new RuntimeException("Malformed URL Exception", urlEx);
        } catch (IOException ioEx) {
            ioEx.printStackTrace();
            throw new RuntimeException("IO Exception", ioEx);
        } finally {
            try {
                if(null!=reader)
                    reader.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
Rahul Prasad
  • 747
  • 1
  • 9
  • 13