I need to extend Exception class in my application and i ran into a situation.
My Parent Exception class with a httpCode setter/getter to translate the exception to http error code:
abstract class ParentException
{
private int httpCode;
protected ParentException()
{
this("");
}
public ParentException(String message)
{
super(message);
}
protected ParentException(Exception e)
{
super(e);
}
public int getHttpCode()
{
return httpCode;
}
public void setHttpCode(int httpCode)
{
this.httpCode = httpCode;
}
}
Sub class:
public class AccessDeniedException extends ParentException
{
public AccessDeniedException()
{
this("");
}
public AccessDeniedException(String message)
{
super(message);
setHttpCode(HttpCodes.HTTP_CODE_403_FORBIDDEN_UNAUTHORIZED);
}
public AccessDeniedException(Exception e)
{
super(message);
setHttpCode(HttpCodes.HTTP_CODE_403_FORBIDDEN_UNAUTHORIZED);
}
}
Similarly i have bunch of other exception implementations for various relevant http codes. What I do not like is that setHttpCode() method is in two places. I want this to be called just from one constructor.
I could have just one constructor in all classes as following (ofcourse I need to fix parent class similarly):
public class AccessDeniedException extends ParentException
{
public AccessDeniedException()
{
this("");
}
public AccessDeniedException(String message)
{
this(message, null);
}
public AccessDeniedException(Exception e)
{
this("", e);
}
public AccessDeniedException(String message,Exception e)
{
super(message, e);
setHttpCode(HttpCodes.HTTP_CODE_403_FORBIDDEN_UNAUTHORIZED);
}
}
But I am worried that if a constructor with just message or exception is called, root Exception or Throwable classes may not get instantiated properly. Do you see any issue with this approach? If not, what is the better way of doing this.
One way would be to have in the base class:
protected abstract int getHttpCode();
And then every child class would need a:
#Override
protected getHttpCode() {
return HttpCodes.HTTP_CODE_403_FORBIDDEN_UNAUTHORIZED;
}
If you do it the second way you should probably pass in null as the message for the empty and Exception constructors.
The second approach will work OK, but you might see slightly different output compared to the first, as some Throwable constructors fill the detailMessage differently.
The same issue as described here was is seen in Exception's extension of Throwable. They solve it in the same way as your first example.
Of the two, I'd recommended using your first example as it follows the established convention and is more robust design if the superclass behavior changed.
Edit - M. Prokhorov noted that there should be an abstract getter method, this approach would work and is better design. Further along those lines I would suggest including the httpCode as part of the constructors of Parent.
e.g.
protected ParentException(int httpCode)
{
super();
this.httpCode = httpCode;
}
public AccessDeniedException()
{
super(HttpCodes.HTTP_CODE_403_FORBIDDEN_UNAUTHORIZED);
}
You could also extract the code to a constant (static final) variable.
Related
Let's say I have an abstract class, called Logger:
public abstract class AbstractLogger {
public enum Levels {
DEBUG, INFO, WARNING, ERROR
}
public void debug(String message) {
Levels level = Levels.DEBUG;
log(level, message);
}
public void info(String message) {
Levels level = Levels.INFO;
log(level, message);
}
public void warning(String message) {
Levels level = Levels.WARNING;
log(level, message); }
public void error(String message) {
Levels level = Levels.ERROR;
log(level, message); }
public void log(Levels level, String message) {}
}
And I also have classes that inherit this class, such as FileAppenderLogger:
public class FileAppenderLogger extends AbstractLogger {
private final Path logPath;
public FileAppender(Path logPath) {
this.logPath = logPath;
createLogFile();
}
private void createLogFile() {
try {
File logFile = new File(logPath.toString());
if (logFile.createNewFile()) {
System.out.println("File created: " + logFile.getName());
} else {
System.out.println("File already exists.");
}
} catch (IOException e) {
System.out.println("An error occurred.");
e.printStackTrace();
}
}
#Override
public void log(Levels level, String message) {
try {
FileWriter myWriter = new FileWriter(this.logPath.toString());
myWriter.write(message+"\n");
myWriter.close();
System.out.println("Successfully wrote to the file.");
} catch (IOException e) {
System.out.println("An error occurred.");
e.printStackTrace();
}
}
#Override
public void debug(String message) {
super.info(message);
}
#Override
public void info(String message) {
super.info(message);
}
#Override
public void warning(String message) {
super.warning(message);
}
#Override
public void error(String message) {
super.error(message);
}
}
Now, let's say I need to extend Logger to support new Log level, such as "FATAL", and also extend its children, such as FileAppenderLogger to support it, without modify any of those classes, only extend them.
what could be the best practice for that (if I still want to preserve non generic methods such as ".info(String s)" or ".debug(String s))?
What design pattern may I use here?
I'm open for changes regard this problem.
Thank you!
Simply add it to AbstractLogger:
public abstract class AbstractLogger {
public enum Levels {
DEBUG, INFO, WARNING, ERROR, /* added */ FATAL,
}
public void fatal(String message) {
log(Levels.FATAL, message);
}
}
Given that the types that extend AbstractLogger all already implement the log method, then 'things will just work' - possibly some of the implementations cannot deal with the fact that a new log level has now appeared. Assuming they were appropriately programmed, they'll throw. Your FileAppenderLogger class, for example, would just continue to work without requiring any change or even recompilation.
The key design pattern to make this work is that all those non-generic methods such as .error(x) are light wrappers that all send the data to a single method that does the real work - log. But, you already do that.
NB: Reinventing the wheel is a bad idea. Logging frameworks already exist, use an existing one instead.
NB2: Idiomatic java dictates you call your enum types the singular - it should be Level, not Levels. The type name describes, well, a type name. It's called String, not Strings, because an instance of java.lang.String represents one string. The class itself represents all strings, but that doesn't mean it should be called Strings. Similarly, an instance of the Levels enum represents a single level. Hence, it should be named Level, not Levels.
Instead of using enum for level, you can make class LogLevel and make classes that extend it, for example LogLevelError, LogLevelFatal, then in log method: this.logLevel.log(message);. Of course, it look strange, but this is the way I see to add new log levels. Also, as said by #rzwitserloot :"NB: Reinventing the wheel is a bad idea. Logging frameworks already exist, use an existing one instead". They are much faster, optimized, and 'time-tested'.
You can't add more values to your enum, that's not possible in java. I would suggest to either use a String for levels, or declare your own Level class, so you can add more levels.
public class Level {
private final String levelName;
//getter, etc.
}
To extend the functionality of your AbstractLogger, without modifying it, you can wrap it in another class and declare the additional methods, fatal() in this case.
public class ExtendedLogger extends AbstractLogger {
private final AbstractLogger abstractLogger;
public ExtendedLogger(AbstractLogger abstractLogger) {
this.abstractLogger = abstractLogger;
}
#Override
public void debug(String message) {
abstractLogger.debug(message);
}
//info, warning and rest of methods
#Override
public void log(Levels level, String message) {
abstractLogger.log(level, message);
}
public void fatal(String message) {
//implement
}
}
First: logger libraries are numerous, and the first reform was the introduction of java.util.Logger to unify things a bit. Still not the dead of the other logging libraries.
Then came - especially for libraries - the underestimated System.Logger: a Logger façade that can be discover logging implementations. This allows publishing a library, use Logging, but leave the actual logging library choice to the library user.
So in that context meddling in class hierarchies and enum constants is counter-productive to say the least.
What you can do is a specific configuration, say for some packages, implement a specific file handler (FileHandler, Handler), and reserve ERROR for your own FATALISH when using *Exception classes or such.
Though seemingly simple, using FileWriter in the Logger child was not intended to be done as such. You should leave it to configuring the usage to your own Handler class.
Unfortunately the solution does not exist. You'll better write a prototype to test your specific configuration.
How could I new an InvocationException in Java ?
InvocationException needs an ObjectReference in its constructor, I don't know how to create one.
Do you mean InvocationTargetException?
From the API: Is a checked exception that wraps an exception thrown by an invoked method or constructor.
Not sure what you try to achieve, maybe share some code and describe your intentions, however if you want to extend this exception then:
package .....;
import java.lang.reflect.InvocationTargetException;
public class SampleException extends InvocationTargetException {
protected SampleException() {
super();
}
public SampleException(Throwable target) {
super(target);
}
public SampleException(Throwable target, String s) {
super(target, s);
}
#Override
public Throwable getTargetException() {
return super.getTargetException();
}
#Override
public Throwable getCause() {
return super.getCause();
}
}
Maybe you want to override getTargetException with something specific to your requirement to catch InvocationTargetException and rethrow with your specific exception?
try{
.....
}catch(InvocationTargetException e){
//Do something with e?
throw new SampleException(); //Rethrow?
}
As I said not much information given.
Is there a way to always execute a function before any other function of a class is called?
I have a class where I need to refresh some fields always before any function is called:
public class Example {
private int data;
public void function1(){
}
public void function2(){
}
//#BeforeOtherFunction
private void refresh(){
// refresh data
}
}
Because it seems to be bad programming, I don't want to call refresh at the beginning of every other function. Since other persons are going to work on this project as well, there would be the danger, that somebody extends the calls and doesn't call refresh.
JUnit has a solution for this with the #Before-Annotation. Is there a way to do this in other classes as well?
And by the way: If you know a programming pattern wich solves this problem in another way than executing a function everytime any function is called, that would be very helpful, too!
Use a dynamic proxy in which you can filter to those methods before which your specific "before" method should be called. And call it in those cases before dispatching the call. Please see the answer from How do I intercept a method invocation with standard java features (no AspectJ etc)?
UPDATE:
An interface is needed to be separated for the proxy. The refresh() method cannot remain private. It must be public and part of the interface (which is not nice here) to be able to be called from the proxy.
package CallBefore;
public interface ExampleInterface {
void function1();
void function2();
void otherFunction();
void refresh();
}
Your class implements that interface:
package CallBefore;
public class Example implements ExampleInterface {
#Override
public void function1() {
System.out.println("function1() has been called");
}
#Override
public void function2() {
System.out.println("function2() has been called");
}
#Override
public void otherFunction() {
System.out.println("otherFunction() has been called");
}
#Override
public void refresh() {
System.out.println("refresh() has been called");
}
}
The proxy which does the trick. It filters the needed methods and calls refresh().
package CallBefore;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
public class ExampleProxy implements InvocationHandler {
private ExampleInterface obj;
public static ExampleInterface newInstance(ExampleInterface obj) {
return (ExampleInterface) java.lang.reflect.Proxy.newProxyInstance(obj.getClass().getClassLoader(),
obj.getClass().getInterfaces(), new ExampleProxy(obj));
}
private ExampleProxy(ExampleInterface obj) {
this.obj = obj;
}
#Override
public Object invoke(Object proxy, Method m, Object[] args) throws Throwable {
Object result;
try {
if (m.getName().startsWith("function")) {
obj.refresh();
}
result = m.invoke(obj, args);
} catch (InvocationTargetException e) {
throw e.getTargetException();
} catch (Exception e) {
throw new RuntimeException("unexpected invocation exception: " + e.getMessage());
}
return result;
}
}
The usage:
package CallBefore;
public class Main {
public static void main(String[] args) {
ExampleInterface proxy = ExampleProxy.newInstance(new Example());
proxy.function1();
proxy.function2();
proxy.otherFunction();
proxy.refresh();
}
}
Output:
refresh() has been called
function1() has been called
refresh() has been called
function2() has been called
otherFunction() has been called
refresh() has been called
This may not solve your exact problem but at least could be a starting point if you are allowed considering a re-design. Below is a simple implementation but with some small touches I believe you can achieve a more elegant solution. BTW, this is called Dynamic Proxy Pattern.
First thing you need is an interface for your class.
public interface Interface {
void hello(String name);
void bye(String name);
}
public class Implementation implements Interface {
#Override
public void hello(String name) {
System.out.println("Hello " + name);
}
#Override
public void bye(String name) {
System.out.println("Bye " + name);
}
}
Then java.lang.reflect.Proxy class comes to help. This class is able to create an instance for a given interface at runtime. It also accepts an InvocationHandler which helps you to capture method calls and looks like this.
public class InvocationHandlerImpl implements InvocationHandler {
private final Object instance;
public InvocationHandlerImpl(Object instance) {
this.instance = instance;
}
#Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
Object result;
try {
System.out.println("Before");
result = method.invoke(instance, args);
System.out.println("After");
} catch (Exception e){
e.printStackTrace();
throw e;
} finally {
System.out.println("finally");
}
return result;
}
}
After all your client code will look like this.
Interface instance = new Implementation();
Interface proxy = (Interface)Proxy.newProxyInstance(
Interface.class.getClassLoader(),
new Class[] { Interface.class },
new InvocationHandlerImpl(instance));
proxy.hello("Mehmet");
proxy.bye("Mehmet");
Output for this code is
Before
Hello Mehmet
After
finally
Before
Bye Mehmet
After
finally
I would define getters for every field and do the refreshment inside the getter. If you want to avoid unrefreshed access to your private fields at all, put them in a superclass (together with the getters which call refresh).
Depending on your project structure, it may be also sensible to introduce a separate class for all data that is regularly refreshed. It can offer getters and avoid that anyone accesses the non-refreshed fields.
Not in Java SE, but if you are using Java EE, you could use interceptors.
For standalone applications, you could consider using a bytecode manipulation framework, like javassist.
You can have a protected getter method for data. Access getData method instead of using data field. Child classes will see only getData and will have updated data every time.
public class Example {
private int data;
public void function1(){
}
public void function2(){
}
protected int getData(){
refresh();
return data;
}
//#BeforeOtherFunction
private void refresh(){
// refresh data
}
}
It is better to write another method which will be made protected(accessible to the child classes) which will call first the refresh method and then call the function.
This way the data would be refreshed before the function is called everytime(As per your requirement).
eg:
protected void callFunction1(){
refresh();
function();
}
Thanks,
Rajesh
You should use Decorator in this case. Decorator is a good choice for something like interceptor. Example here: https://msdn.microsoft.com/en-us/library/dn178467(v=pandp.30).aspx
How I can scan my code and get all possible throws MyException errorCode's of execute() function?
Errors const:
public enum ErrorId {
OK(1),
REPORT_LIMIT(2),
NOT_UNIQUE_FIELD(3),
INCORRECT_PROPERTY(4);
private int id;
ErrorId(int id) {
this.id = id;
}
}
For example I have 'MyException' :
public class MyException extends Exception {
#Getter
protected final ErrorId errorCode;
public MyException(ErrorId errorCode) {
this.errorCode = errorCode;
}
}
And class with method:
public class MyClass {
public void execute() throws MyException {
//do something 1
...
if(isSomethingWrong1) throw new MyException(ErrorId.REPORT_LIMIT);
executeMethod2();
//do something N
if(isSomethingWrongN) throw new MyException(ErrorId....);
}
public void executeMethod2() throws MyException {
// ...
throw new MyException(ErrorId....)
// ...
}
}
I don't think there's an answer here that you'll like.
Reflection won't work in this case, because it's concerned with types, not values. The compiler can't help you here, either, because if the error code comes in through a variable, then at runtime, all bets are off -- the value could be any possible value of the type you're using. If you're using an enum for the code value, then you have a known list of all possible values, but you won't know which ones are actually used in any particular function without reading that function. A static analysis tool may be of use here, but you'd need to continue running it over time to keep this information up to date.
However, all is not lost. As I said in my second comment, you have another choice -- extract subclasses. Let's consider this definition of your Exception class.
public abstract class MyException extends Exception {
#Getter
protected final ErrorId errorCode;
public MyException(ErrorId errorCode) {
this.errorCode = errorCode;
}
}
It's the same as yours is now, but it's abstract. This class is open for extension. So we could create a subclass ReportLimitException like this:
public class ReportLimitException extends MyException {
public ReportLimitException() {
super(ErrorId.REPORT_LIMIT);
}
}
and another like this, for example:
public class DuplicateFieldException extends MyException {
public DuplicateFieldException() {
super(ErrorId.NOT_UNIQUE_FIELD);
}
}
Now, any given method can advertise which particular exceptions it uses via its throws clause. This is, in fact, why that clause exists.
public void execute() throws ReportLimitException, DuplicateFieldException {
//do something 1
//...
if(isSomethingWrong1) throw new ReportLimitException();
executeMethod2();
//do something N
if(isSomethingWrongN) throw new DuplicateFieldException();
}
At this point, if you advertise the exceptions explicitly, you'll have achieved your goal, at the cost of some potentially long throws clauses (which should actually be a hint to you that the method may be doing too much work anyway). Alternatively if you don't want to advertise every exception like that, you could also use your IDE's "find references" feature to locate every place where those exceptions are created (look for references to the constructors).
And the calling code doesn't even have to be aware of the change. It can continue using code like this:
try {
// stuff that might throw any of your exceptions
} catch (MyException ex) {
switch (ex.getErrorCode()) {
// handle the cases...
}
}
I have classes with methods implemented as follow:
void methodOne() {
try {
getHelper().doActionOne();
} catch ( Exception ex ) {
throw new CustomException( ex );
}
}
void methodTwo() {
try {
getHelper().doActionTwo();
} catch ( Exception ex ) {
throw new CustomException( ex );
}
}
void methodThree() {
try {
getHelper().doActionThree();
} catch ( Exception ex ) {
throw new CustomException( ex );
}
}
void methodFour;
void methodFive;
...
Is there a better way to do this? These codes make me uncomfortable.
EDIT:
Sorry for unclear example. I'm implementing GenericDao class with Hibernate, the real code is something like this:
class GenericDaoImpl<T, PK> {
PK create( T object ) {
try {
getSession().save( object );
} catch( Exception ex ) {
throw new DataAccessLayerException( ex );// wrap any exception to my exception
}
}
T read( PK id ) {
try {
getSession().get( T.class, id );
} catch ( Exception ex ) {
throw new DataAccessLayerException( ex );
}
}
void update( T object );
void delete( T object );
}
Just a basic suggestion, but you could refactor this into something like a "Command Pattern." This pattern allows you to encapsulate some functionality into a class that implements a single method. The class can be instantiated and passed into another class to be executed, and the executor class doesn't have to know or care what it's doing, it just needs to call execute(). If the actions require arguments, the classes that implement Command can include fields/properties that can be set in the constructor or by standard property setters.
Make an interface like this (my Java is rusty, so this may not be 100% valid syntax):
public interface Command
{
public void execute();
}
public class ActionOne implements Command
{
public void execute()
{
// do actionOne...
}
}
public class ActionTwo implements Command
{
public void execute()
{
// do actionTwo...
}
}
// etc. for more actions
Then create the class that executes the action, and the calling code just needs to pass in the correct Command implementation class.
public class Executor
{
public void executeCommand(Command command)
{
try
{
// Put any boilerplate code here (logging, auditing, etc.)
command.execute();
}
catch (Exception ex)
{
// Put general error handling code here. If you're just catching and rethrowing, consider not catching the Exception at this level. If it's a checked exception, add a throws clause to the method.
throw new CustomException();
}
}
}
Yes, you can always refactor code. The only issue is whether you're going to refactor to make it better or worse. The hints that this code is odd, is a good hint that it can be made much better.
This looks like a good candidate for polymorphisim. Instead of five different methods, try five different classes with one shared method. The interface will tie it all together.
public interface DoIt {
public void doIt();
}
public class One implements DoIt {
public void doIt() {
// code which was previously in getHelper.doActionOne();
}
}
public class Two implements DoIt {
public void doIt() {
// code which was previously in getHelper.doActionTwo();
}
}
...
public class Five implements DoIt {
public void doIt() {
// code which was previously in getHelper.doActionFive();
}
}
Now the only thing is to create the right class for the situation, and call its doIt() method.
This facility is provided by the Spring Framework along with many others. First, it has a specific HibernateTemplate which maps each Hibernate-specific exception to an unchecked, related Spring exception. Second, it provides an AOP service to translate exceptions at the method level so you can specify the mappings once and apply them uniformly across multiple services.
While I wouldn't use Spring for just this one feature, it has huge benefits for building applications and I have continued using it for many years.