How to avoid exceptions when creating a URL? - java

In a JUnit test package, I create a java.net.URL object and use it in a variety of assert statements. However, the constructor for the URL Object throws a MalformedURLException that must be caught. Since that must be caught, the constructor must then be wrapped in a try/catch, and that means you have to put the variable in scope outside of the try/catch.
Example code:
URL ocURL = null;
try {ocURL = new URL("https://docs.oracle.com/javase/8/docs/api/java/net/URL.html");}
catch (MalformedURLException e) {}
assertEquals(variable, ocURL)
Admittedly, this is entirely aesthetic: I don't like all the extra code with no meaning littering my screen. Since I am passing the URL as a string, I know that it is going to be good, so that exception cannot be thrown (famous last words, though).
Is there a way to avoid declaring the URL object, then initializing it inside a try/catch? Is there a way to build a java.net.URL object without having to catch a (non-existent) exception?

create a static factory method instead and handle the try/catch only once:
private static URL createURL(String path) {
try {
return ....;
} catch(MalformedURLException e){
// handle somehow
throw new RuntimeException(e);
}
}

Related

Unhandled exception type Exception in Eclipse

I have the class Parser in Java like below:
public class Parser {
public ArrayList<MetroStop> listeArrets;
public Parser() {
this.listeArrets = new ArrayList<>();
}
public MetroStop creerArret(String [] parts) {
MetroStop arret = new MetroStop ();
arret.identifiant = Integer.parseInt(parts [0]);
arret.longitude = Double.parseDouble(parts [1]);
arret.latitude = Double.parseDouble(parts [2]);
arret.nom = parts [3];
arret.destination = parts [4];
arret.moyen = parts [5];
return arret;
}
public void parse(String fichier) throws Exception {
try {
Reader reader = new FileReader(fichier);
BufferedReader br = new BufferedReader(reader);
String line;
while((line = br.readLine ()) != null) {
String [] parts = line.split("#");
MetroStop arret = creerArret(parts);
listeArrets.add(arret);
}
br.close();
} catch (FileNotFoundException e) {
throw new RuntimeException(e);
}
}
}
I also have the Main class:
public class Main {
public static void main(String[] argv) {
Parser teste = new Parser();
teste.parse("ratp_arret.csv");
}
}
When I run the Main class as Java Application i get this error:
"Unhandled exception type Exception", which points to the second line of the main() method.
The file ratp_arret.csv is located in the src folder, which is also the working directory.I am using Eclipse.
I don't understand where this error comes from.
Thank you for your help!
You call teste.parse(someString), where teste is an expression which has type Parser. That means this is a call to the method parse(String) in your Parser type....
and that is declared with throws Exception.
Exceptions are a mechanism to convey alternate return options. The parse method can run its course in one of two ways: It can 'return', in which case it returns nothing (void), or, it can 'throw'. What it can throw is limited by its throws line - in this case, it can throw just about anything (Exception is the supertype of almost all things you can throw).
The way java handles this is that your code needs to handle every possible way a method can conclude.
So, you need a 'path' for your code when the parser() method returns (this is trivial; it's a void method, you get that 'for free', you don't need to write anything special for this), but you also need a path for that other exit scenario: When it throws something. You get handling of RuntimeException for free, but for others, you have two options:
catch it:
try {
teste.parse(someString);
// this code runs in the 'return' case.
} catch (Exception e) {
// this code runs in the 'throws' case.
}
this would imply you know what to do when your parse method decided to exit via the throws path.
Alternatively, you fix this by having your main method also 'fork', and decree that it has two ways to finish: Either via the return route or the throw route:
public static void main(String[] args) throws Exception {
teste.parse(someString);
}
// this main method has declared that it has two separate
// exit routes. 'return', and 'throws something'.
java will start an application by running its main method, and java can deal with a main that has two alternate exit routes (return, or throw something). It handles the 'return' route by doing nothing. It handles the 'throw something' route by printing the type of the exception, the message, the stack trace, and the entire causal chain. That is an excellent default, and you should not attempt to come up with a different one by e.g. catching that exception and attempting to 'log it'.
This: Just add throws Exception to your main method declaration. Put the throws Exception back on your parse method, ignore #Eritrean's advice.
NB: All methods are inherently declared as if they said throws RuntimeException, Error (as in, any error and any runtimeexception can be thrown without writing a throws clause for it, as all methods implicitly have that clause baked in already), this is why I said earlier that RuntimeExceptions are 'handled for free'. The idea is that all exceptions that subclass RuntimeException are things that are so universal or so unlikely, it would be unwieldy to force management of this onto the programmer. That's why you never need to write throws NullPointerException or throws InternalError.
public void parse(String fichier) /*throws Exception*/ {
try {
// ...
} catch (FileNotFoundException e) {
throw new RuntimeException(e);
}
}
You throw RuntimeException. This is called not-checked exception and it's not mandatory to declare these exeptions in the method declaration and catch it when calle the method.

How to propagate exception from an overridden method in Java

What is the best practice to terminate the execution of an overridden method?
Here is the example code that explains the context:
#Override
protected String doInBackground(String... params) {
URL serverURL = null;
try {
serverURL = new URL((urlString));
} catch (MalformedURLException e) {
e.printStackTrace();
}
...
...
return response.toJSONString();
}
In the above code snippet, I am forced to catch MalformedURLException, so I used the try catch block. If that exception occurs, I would like to skip all the code below the catch block and propagate either the same exception or a different one that I would throw within the catch block until all the way to the Main method, hopping through the catch blocks and skipping the code in the middle in all the calling methods. How to do this?
The problems are:
1) I cannot add throws clause to the method signature because it is overridden and the base class doesn't allow it.
2) Since the method has to return a String, I have to specify the return statement after the catch block.(What do I return if an exception has occurred?)
3) Use System.exit in catch block - As some other posts on this forum point out, that may not be a good practice when you want your code to be reusable.
The best practice for such a case would be to wrap the MalformedURLException with a RuntimeException:
catch (MalformedURLException ex) {
throw new RuntimeException("Failed constructing URL", ex);
}
Ideally, you'd really like to edit the method's throws clause so it can accommodate any exceptions that are likely to stem from overrides; but since this is impossible in your case (as per your conditions), the above seems most reasonable to me.
A related best-practice would be to avoid logging the exception before wrapping it. From a design perspective, there's no need to do so — the caller already has access to the original Exception object (through the getCause() method of the thrown RuntimeException) so the caller should decide whether to log it or not.

Java casting an exception (not class cast exception)

When an exception is caught in java is there a use case for casting the exception to a new type? Or is the standard
throw new DiffException(e)
The only way to do it. I apologize if I'm overlooking something but the only search results I get are for "ClassCastExceptions" Which is obviously not what I'm looking for
I believe you meant 'exception wrapping'.
There's no other way to do it - you create a new instance of Exception using a constructor which takes another exception as cause. This works thanks to 1-arg constructor of java.lang.Exception. The typical implementation of custom exception type (like your DiffException) declares such 1-arg constructor too.
Well, if the exception caught (e in your case I suppose) is a subtype of DiffException, you could of course cast it like
throw (DiffException) e;
but I doubt that's what you want to do, since it doesn't make a difference (the e will still have the same runtime type, even in the receiving end).
So the answer is most likely, no, there is no other, equivalent way, of doing
throw new DiffException(e);
than doing just that.
It should be noted however, that doing new DiffException(e) is not called casting but, wrapping, or chaining the exception.
If I understand you correctly here is the use case I am thinking about.
expression:
new FileInputStream("the path");
may throw FileNotFoundException if the file does not exist. FileNotFoundException extends IOException, so you could write code like:
public void readFromFile(String path) {
InputStream in = new FileInputStream(path);
// do something....
}
Now you can call this method as following:
try {
readFromFile("myFile");
} catch (IOException e) {
if (e instanceof FileNotFoundException) {
FileNotFoundException fnfe = (FileNotFoundException)e;
// do something
}
// do something else
}
But I'd recommend you create separate catch blocks for FileNotFoundException and for IOException (at least for this use-case):
try {
readFromFile("myFile");
} catch (FileNotFoundException e) {
// do something with FileNotFoundException
} catch (IOException e) {
// do something with IOException
}
This code does not contain instanceof, casting and other ugly stuff.
Since you mentioned use cases, the common one in Java is wrapping a checked exception as unchecked; this is appropriate when there's no way the checked exception can occur, such as here:
public static Reader getUTF8Reader(InputStream is) {
try {
return new InputStreamReader(inputStream, "UTF-8");
} catch(UnsupportedEncodingException e) {
// should never happen since UTF-8 is guaranteed to be available as per
// http://download.oracle.com/javase/6/docs/api/java/nio/charset/Charset.html
throw new RuntimeException("UTF-8 not available", e);
}
}
Without wrapping the exception, you'd either have to swallow it (which feels wrong) or declare the method as throws UnsupportedEncodingException which forces anyone using it to catch the exception that will never be thrown. Wrapping it, there's no onus on the caller to handle unlikely cases, yet we're protected in the unlikely event that UTF-8 isn't available on some obscure platform in the future.

Java - Can final variables be initialized in static initialization block?

Based on my understanding of the Java language, static variables can be initialized in static initialization block.
However, when I try to implement this in practice (static variables that are final too), I get the error shown in the screenshot below:
Yes of course: static final variables can be initialized in a static block but.... you have implicit GOTOs in that example (try/catch is essentially a 'GOTO catch if something bad happens').
If an exception is thrown your final variables will not be initialized.
Note that the use of static constructs goes against Object-Oriented dogma. It may complicate your testing and make debugging more difficult.
You can do this but you need to exit the static block by throwing an exception - you can rethrow the exception that was caught or a new one. Generally this exception must be a RuntimeException. You really should not catch a generic Exception but more specific exception(s) that might be thrown from within your try block. Finally, if a static initializer throws an exception then it will render the class unusable during that specific run because the JVM will only attempt to initialize your class once. Subsequent attempts to use this class will result in another exception, such as NoClassDefFoundError.
So, to work, your initializer should read something like this:
static {
try {
...
} catch (Exception e) {
e.PrintStackTrace();
throw new InitializationFailedException("Could not init class.", e);
}
}
Assuming that InitializationFailedException is a custom RuntimeException, but you could use an existing one.
public class MyClass
{
private static final SomeClass myVar;
static
{
Object obj = null; // You could use SomeClass, but I like Object so you can reuse it
try
{
obj = new SomeClass(...);
}
catch(WhateverException err)
{
// Possibly nested try-catches here if the first exception is recoverable...
// Print an error, log the error, do something with the error
throw new ExceptionInInitializerError(err);
}
finally
{
myVar = (SomeClass) obj;
}
}
}
Assuming no where upstream is in a position to catch either an ExceptionInInitializationError or a general Exception then the program should not ever try to use myVar. If however those are caught and the program doesn't end, then you need to code to watch for and handle myVar being null (or be happy with NullPointerExceptions coming out all over).
I'm not sure there is a good way to handle this.
Can you put the declaration in the finally block?
try {
//load file
} catch(IOException e) {
// horay
} finally {
HOST=config.get......
}

is there a way to both catch and throw an exception

I have a method that is going to the DB so all our JDBC stuff in the DAO method is inside a try/catch block. It is catching SQLException
When I write a test case against this method and if a SqlException occurs then my testcase does not say 'caused an error'. it just goes on its merry way.
However, If I dont catch the SqlException in the DAO method but add throws SqlException to the method instead then my test case says 'caused an error' and shows me the error that happened. (this is what I want).
When I try adding throws SqlException along with the method catching the SqlException then also my test case does not say 'caused an error'.
what is the way around it? one is to have try/catch block inside my test case but even if I do this my Junit test case does not say 'caused an error' though the exception IS posted to standard output.
...but besides that anything else?
My IDE is Netbeans. this is where I run the test cases.
Code:
public class MyDaoClass {
Connection con;
public MyDaoClass (Connection connection)
{
this.con = connection;
}
public SomeObject someMethod (String id)
{
try{
Connection con = this.con;
CallableStatement cs = con.prepareCall("{call some_sp_name (?)}");
cs.setString (1, id);
cs.execute()//imagine an error happens here
ResultSet rs = cs.getResultSet()
...
....
//return SomeObject...
}
catch (SqlException e) //If I remove this and add 'throws SQLException to method then everything is ok
{
log.error(e.getMessage());//i dont have access to log object in test case
}
}
}
public class MyTestSuite extends TestCase
{
//populate local connection
public void testSomeMethod () throws SQLException
{
MyDaoClass myd = new MyDaoClass(connection);
SomeObject s = myd.someMethod("blah");
assertEquals (s.getFirstName(), "pepe");
}
}
All checked exceptions in Java must be declared in the method specification. SqlException is a checked exception, so if you want to throw it, you must include it in the specification.
If you want to throw an exception, but you can't change the method specification, you need to use an unchecked exception, like RuntimeException. It will also cause JUnit to show the error that happened.
The Java Tutorials: Exceptions is an excellent reference on this topic.
If you add throws SQLException to the method, then you don't have to try-catch it anymore.
And yes, you can catch and throw an exception:
try {
// some code
}
catch (SomeException e) {
throw e;
// or,
// throw new SomeOtherException();
}
JUnit doesn't care what you write to standard output. If the exception leaks out of your method, then JUnit takes notice.
If you catch the exception inside your method, then it's correct behavior for the exception not to come out of your method, because it was (we hope!) handled there. So a passing test is a Good Thing.
What you should be testing for is whether your method is producing the correct result (whatever that may be) even in circumstances when an exception is thrown (and handled).
that is not the full code is it? the compiler would complain that someMethod is not always returning a value.
If you want to keep the method as is, then at least add "return null;" after the try/catch.
That way, if an SQLException occurs, then assertEquals should throw NullPointerException which should work on your TestCase.
Side advice, i would check if connection is not null before using it.
Instead of re-throwing the exception, you can also return a null reference instead of an empty or incomplete object. Your callers must check for null's and handle the case when the DAO fails to load the object.
Alternatively, you can stub the log object in your JUnit test and inject it into the DAO via an alternative constructor. Your stubbed logger subclass can deliver the message to your test for inspection.
In addition to what Chip Uni said above re: Runtime exceptions to not need to be declared,
you should also note that exceptions can be nested, i.e.
catch (SqlException e)
{
throw new RuntimeException(e);
}
This will throw a RuntimeException that contains an SqlExceotion.

Categories