I never really thought about this before but looking at the following code
public class SomeJavaProgram {
private static String runMe() {
throw new RuntimeException("hi tadsfasdf");
}
private static String name = runMe();
public static void main(String[] args) {
System.out.println("hi there.");
}
}
I never did statics like this in a main before but then I entered scala, and if you have subclasses that start adding defs, exceptions can be thrown before main is even called.
So, in java(not scala), is there a way to catch these exceptions(if I am the superclass and subclasses end up having a static field that throws an exception or static initializer block)....how can I catch all these?
I of course do rely on ONE single definition not throwing which is the
private Logger log = createLoggerFromSomeLoggingLib();
But after that, ideally I would want all exceptions to be logged to the logged file rather than stderr.
That said, I am glad I have always kept the stderr/stdout files along with my logging files now.
Use the static initializer:
private static String name;
static {
try {
name = runMe();
} catch (RuntimeException e) {
// handle
}
}
Related
I'm trying to figure out a way to build a method that will test whether a checked exception has indeed been thrown. As I was building the following minimal working example (CustomThrowablexxx are all custom types declared on their own files for readability):
package demos.exceptions;
public class TestExceptions {
// This method will check whether the provided method throws exceptions
// of the type provided.
private static boolean throwsParticularThrowable(Runnable method,
Class<Throwable> cls){
try {
method.run();
} catch(Throwable t){
if(t.getClass().equals(cls))
return true;
}
return false;
}
private static void methodOne() throws CustomThrowableOne {
throw new CustomThrowableOne("methodOne() throws");
}
private static void methodTwo() throws CustomThrowableTwo {
throw new CustomThrowableTwo("methodTwo() throws");
}
private static void methodThree() throws CustomThrowableThree {
throw new CustomThrowableThree("methodThree() throws");
}
public static void main(String[] args){
if(!throwsParticularThrowable(TestExceptions::methodOne,
CustomThrowableOne.class))
System.out.println("Nope!");
}
}
I unfortunately noticed that the access to TestExceptions::methodOne was not safe, because the compiler complained that I'm not checking for the throwing of methodOne, which I guess makes sense.
Is there any way I can automate this instead of copying and pasting the code inside throwsParticularThrowable every time?
I don't know what you are looking for but it's easier to test if exceptions are thrown using JUnit ExpectedException
https://junit.org/junit4/javadoc/4.12/org/junit/rules/ExpectedException.html
To use logger with Java, for now I'm using code like this:
Logger logger = Logger.getLogger("MyLog");
FileHandler fh;
try {
// This block configure the logger with handler and formatter
fh = new FileHandler("c:\\MyLogFile.log", true);
logger.addHandler(fh);
logger.setLevel(Level.ALL);
SimpleFormatter formatter = new SimpleFormatter();
fh.setFormatter(formatter);
// the following statement is used to log any messages
logger.log(Level.WARNING,"My first log");
} catch (SecurityException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
But it always disturbs me somewhat to add this for every class file:
Logger l = Logger.getLogger("MyLog");
How could I refactor out this duplication?
Is there a better recommended way for logging, which could be less intrusive/less repeative but offers the same or even better functions?
You could make l a private static or private field of the class, but apart from that there is no significant improvement.
(There are some bad ideas, like a public static "global" variable, or a private static declaration in a "universal" base class. But those are BAD IDEAS ... not better ways.)
But, hey, one line of code to declare your local logger object is hardly "intrusive" ... is it?
Logging in every class file is a right way, alougth it is looks a little redundancy.
The important function for logging is that record exception. If we want to directly find where occurs the exception, we should know the class name and the method name.
But you maybe be forget to logging when catch exception.
We're using reflection and static fields and this API: http://commons.forgerock.org/bom/apidocs/org/forgerock/i18n/slf4j/LocalizedLogger.html#getLoggerForThisClass()
You could use project lombok to do this:
project lombok is here
The following is the example from their webpage should it ever not be available. To be clear it still generates the statements in your resulting bytecode, but it stops the bolierplate, now you'll have a smaller statement to but in, its horses for courses but the project team I currently work on like it.
import lombok.extern.java.Log;
import lombok.extern.slf4j.Slf4j;
#Log
public class LogExample {
public static void main(String... args) {
log.error("Something's wrong here");
}
}
#Slf4j
public class LogExampleOther {
public static void main(String... args) {
log.error("Something else is wrong here");
}
}
#CommonsLog(topic="CounterLog")
public class LogExampleCategory {
public static void main(String... args) {
log.error("Calling the 'CounterLog' with a message");
}
}
Vanilla Java
public class LogExample {
private static final java.util.logging.Logger log = java.util.logging.Logger.getLogger(LogExample.class.getName());
public static void main(String... args) {
log.error("Something's wrong here");
}
}
public class LogExampleOther {
private static final org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(LogExampleOther.class);
public static void main(String... args) {
log.error("Something else is wrong here");
}
}
public class LogExampleCategory {
private static final org.apache.commons.logging.Log log = org.apache.commons.logging.LogFactory.getLog("CounterLog");
public static void main(String... args) {
log.error("Calling the 'CounterLog' with a message");
}
}
I have a singleton class
public class SingletonText {
private static final CompositeText text = new CompositeText(new TextReader("text/text.txt").readFile());
public SingletonText() {}
public static CompositeText getInstance() {
return text;
}}
And TextReader constructor that could throw FileNameEception
public TextReader(String filename) throws FileNameException{
if(!filename.matches("[A-Za-z0-9]*\\.txt"))
throw new FileNameException("Wrong file name!");
file = new File(filename);
}
How can I rethrow it to main and catch it there?
Main class
public class TextRunner {
public static void main(String[] args) {
// write your code here
SingletonText.getInstance().parse();
System.out.println("Parsed text:\n");
SingletonText.getInstance().print();
System.out.println("\n\n(Var8)Task1:");
SortWords.sortWords(SingletonText.getInstance().getText().toString(), "^[AEIOUaeiou].*", new FirstLetterComparator());
System.out.println("\n\n(Var9)Task2:");
SortWords.sortWords(SingletonText.getInstance().getText().toString(), "^[A-Za-z].*", new LetterColComparator());
System.out.println("\n\n(Var16)Task3:");
String result = SubStringReplace.replace(SingletonText.getInstance()
.searchSentence(".*IfElseDemo.*"), 3, "EPAM");
System.out.println(result);
}}
Static block is executed only when class is loaded for the first time, so you can have something as below which will allow you to re-throw the exception. In you main method, you will surround getInstance() invocation in a try-catch block and then in catch you can do whatever you are looking for.
In case of exception, this exception will be thrown and re-thrown (from you static block) only once, at time of class loading. What #Alexander Pogrebnyak has said is also true.
Looking at the code you have provided, since you are always reading text/text.txt files so below approach will work. In case you are looking to read different files and then re-throwing exception then that becomes all together a different story, and you hadn't asked that part neither the code you have provided shows the same. In any case, if that's what you are looking for then:
you need to create a singleton object of your CompositeText class.
create a setter method will create an object TextReader class using the file name string passed.
that setter method will have the try-catch block, and in the catch block you will re-throw the exception so that you can catch again in main method.
P.S.: since static blocks are executed only once when class is loaded and class is loaded only once per JVM (until you have custom class loaders and overriding the behavior) so this ensures that this singleton is thread-safe.
Code:
public class SingletonText {
private static CompositeText text = null;
static{
try {
text = new CompositeText(new TextReader("text/text.txt").readFile());
} catch (FileNameException e) {
// TODO: re-throw whatever you want
}
}
public SingletonText() {}
public static CompositeText getInstance() {
return text;
}
}
try to lazy initialze the singleton.
something like this:
public class SingletonText {
private static CompositeText text;
public SingletonText() {
}
public static CompositeText getInstance() {
if (text ==null) {
text = new CompositeText(new TextReader("text/text.txt").readFile());
}
return text;
}
}
Also, you need to declare the constructor private, and if it multi-threaded application you need to synchronized the new statement with double check locking. see this in wiki:
https://en.wikipedia.org/wiki/Double-checked_locking#Usage_in_Java
Enjoy..
You will get java.lang.ExceptionInInitializerError when your singleton static initializer will fail.
As a cause it will have your FileNameException.
If you don't do anything, default exception handler will print the whole stack trace to standard error.
I have been working on a code that does 2 things:
Has a class that performs computations (logic)
has a class that displays the result.
I am wondering if it is possible to use try/catch statements in the Display class, where I would attempt to catch exceptions originating in the logic class.
Where Display would execute a line similar to logic.execute(input);
I was able to create a custom exception class where the following is placed in display class:
try{
logic.execute(input);
}catch(CustomException e){
//print statements
}
However I would like to be able to print exactly the error that occured, such as NullPointerException.
When i say print, i mean output in console. (but it must originate from display class)
If such a monstrosity is possible, please let me know.
Thank You guys!
Yes, it's possible.
You will need your custom exception class to extend RuntimeException instead of Exception, or the compiler will complain that you are not catching the exception that you throw.
See this post: Throwing custom exceptions in Java
Simple working example:
public class ExceptionTest
{
public static void main(String[] args)
{
SomeClass myObject = new SomeClass();
myObject.testFunction();
}
}
public class SomeClass
{
private SomeOtherClass someOther = new SomeOtherClass();
public void testFunction()
{
try{
someOther.someOtherFunction();
}
catch(Exception e){
System.out.println(e.toString());
}
}
}
public class SomeOtherClass
{
public void someOtherFunction()
{
throw new CustomException("This is a custom exception!");
}
}
public class CustomException extends RuntimeException
{
public CustomException(String message)
{
super(message);
}
}
I have following code:
public class LoadProperty
{
public static final String property_file_location = System.getProperty("app.vmargs.propertyfile");
public static final String application-startup_mode = System.getProperty("app.vmargs.startupmode");
}
It reads from 'VM arguments' and assigns to variables.
Since static final variable is only initialized at class load,
how can I catch exception in case some one forgets to pass parameter.
As of now, when I am using 'property_file_location' variable, exception is encountered in following cases:
If value is present, and location is wrong, FileNotFound exception comes.
If it is not initialized properly(value is null), it throws NullPointerException.
I need to handle second case at time of initialization only.
Similiar is case of second variable.
Whole idea is
To initialize application configuration parameters.
If successfully initialized, continue.
If not, alert user and terminate application.
You can catch it this way:
public class LoadProperty
{
public static final String property_file_location;
static {
String myTempValue = MY_DEFAULT_VALUE;
try {
myTempValue = System.getProperty("app.vmargs.propertyfile");
} catch(Exception e) {
myTempValue = MY_DEFAULT_VALUE;
}
property_file_location = myTempValue;
}
}
You can use a static initializer block as suggested by the rest of the answers. Even better move this functionality to a static utility class so you can still use them as an one-liner. You could then even provide default values e.g.
// PropertyUtils is a new class that you implement
// DEFAULT_FILE_LOCATION could e.g. out.log in current folder
public static final String property_file_location = PropertyUtils.getProperty("app.vmargs.propertyfile", DEFAULT_FILE_LOCATION);
However if those properties are not expected to exist all the time, I would suggest to not initialize them as static variables but read them during normal execution.
// in the place where you will first need the file location
String fileLocation = PropertyUtils.getProperty("app.vmargs.propertyfile");
if (fileLocation == null) {
// handle the error here
}
You may want to use a static bloc :
public static final property_file_location;
static {
try {
property_file_location = System.getProperty("app.vmargs.propertyfile");
} catch (xxx){//...}
}