I am new to Java World.
We have a Java application where it gives a specific type of exception. Is there any way, we can have log4j to react to specific way. Having own appender for something like MQ connection exception, we need to send email to specific group.
We are in the process of customizing a Java out of the application which intern uses MQ and through exception which we need to email.
I am actually looking for how the appender will look like
Yes, you're on the right track. Implement your own Appender and only log things that match what you want to log.
Alternatively, use an existing appender (e.g. SMTPAppender) and implement/utilize an existing Filter to limit what is sent there.
If you mean that you want to append an event only when it contains a certain class of exception, you could write a filter. Something along these lines (untested code!):
public final class ExceptionFilter extends org.apache.log4j.spi.Filter {
private volatile String type;
public void setType(String type) {
this.type = type;
}
public String getType()
return type;
}
public int decide(LoggingEvent evt) {
Throwable t = evt.getThrowableInformation().getThrowable();
if ((t != null) && t.getName().equals(type))
return NEUTRAL;
else
return DENY;
}
}
Related
I'm wondering if there is a clean and complete way to assert on the message attached to a thrown exception when that message was generated using String.format(). For example, a class like:
public class Car {
public static final String DRIVE_ERROR = "Can't drive while car %s is parked!";
private String name;
private boolean parked;
public Car(String name) {
this.name = name;
this.parked = true;
}
public void drive() {
if (parked) {
throw new IllegalStateException(String.format(DRIVE_ERROR, name));
}
}
}
(Sorry for the weird example, just trying to keep it as simple as possible)
Now if I were testing the car, I'd have a class like this:
public class CarTest {
#Test
public void drive_test() {
Car car = new Car("Greased Lightning");
assertThatThrownBy(() -> car.drive())
.isInstanceOf(IllegalStateException.class)
.hasMessageContaining("???");
}
}
The question is, what is the best way to assert on the message? In this example, I could separate out the declaration of the name of the car, then use String format myself to grab the static string from Car and format in the name, but that seems like a lot of extra code, and can't be easily used in a lot of instances (eg. when the item that goes in the formatted string is determined at runtime). What I'd really like to be able to do is pass the error message string to hasMessageContaining and have it ignore the "%s" placeholder and accept anything in that spot. Is there a way to do regex matching of Strings with assertJ? Or some other way of doing this cleanly?
EDIT: I'm also open to alternatives on throwing exceptions that have messages that are easier to test. One solution is just using String concatenation, like throw new Exception(STATIC_ERROR_MESSAGE + name) and then testing that the message contains the first part, but that really limits your message formatting ability and doesn't look very clean.
Exception message assertions are limited compared to regular String assertion.
What you could do is use matches or containsPattern assertions, ex:
#Test
public void test() {
// GIVEN some preconditions
// WHEN
Throwable thrown = catchThrowableOfType(() -> { throw new IllegalStateException("boom!"); },
IllegalStateException.class);
// THEN
assertThat(thrown.getMessage()).matches(".oo.")
.containsPattern("oo.");
// or even better thanks to Rolland Illig suggestion
assertThat(thrown).hasMessageMatching(".oo.");
}
Note that by using catchThrowableOfType you don't have to check that the caught exception is of the expected type anymore.
I was reading documentation on Akka actors implementation in Playframework,
https://www.playframework.com/documentation/2.4.x/JavaAkka
One of the paragraphs talk about message class best practice as following:
"Another best practice shown here is that the messages that HelloActor sends and receives are defined as static inner classes of another class calledHelloActorProtocol:"
Can some one please elaborate and explain this best practice and what are the benefits of this pattern? Why message should be defined as static nested class of other class?
Thank you in advance!
I believe the main idea behind this is to isolate the scope of messages sent to a specific actor. Having typed protocols helps cut down on sending an unexpected Protocol (or message) to the actor. Keeping them in one class is a nice way to capture all the actions related to that specific domain, like EmployeeProtocol helps enforce EmployeeActor to receive expected messages. However, you still have the responsibility to send them correctly:
Here is our controller call to the EmployeeActor using the protocol:
public class EmployeeController extends Controller {
return Promise.wrap(ask(employeeActorRef,
new GetCurrentEmployees(), 5000))
.map(response -> ok((JsonNode)response));
}
}
EmployeeActor processes its messages based on the received protocol:
public class EmployeeActor extends UntypedActor {
#Override
public void onReceive(Object message) throws Exception {
if (message instanceof GetCurrentEmployees) {
//do things related to this task
} else if (message instanceof CreateNewEmployee) {
//do things related to this task
} else if (message instanceof RemoveEmployee) {
//do things related to this task
}
}
}
Here protocols are defined for actions on the employee and can hold typed fields so we know what to expect. The fact that we use static final fields in the protocol will enforce immutability of the messages:
public class EmployeeProtocol {
public static class GetCurrentEmployees {}
public static class CreateNewEmployee {
private final String name;
public CreateNewEmployee(String name) {
this.name = name;
}
//getter
}
public static class RemoveEmployee {
public final String uuidToRemove;
public RemoveEmployee(String uuidToRemove) {
this.uuidToRemove = uuidToRemove;
}
//getter
}
}
Akka-Typed is being developed in akka scala which can be used to send messages of only a specific type so that if you attempt to send an incorrect message type the compiler will complain. Akka-typed - http://doc.akka.io/docs/akka/snapshot/scala/typed.html#typed-scala
Maybe they wanted us to use this best practice because we'll be able to make it type safe in the future... There was also mention of this coming to java here in this podcast: https://www.typesafe.com/resources/video/akka-2-4-plus-new-commercial-features-in-typesafe-reactive-platform
I'm using slf4j + log4j in java to add logging to my web application. In each logged event I want to print the feature the user is executing and an identifier of the user action.
When my webapp catches the user's request, I generate the identifier and I have access to the feature "name". What is the best way to put these two parameters in every event logged without passing it out to every method log.(info|warn|debug|error)?
I know I can use MDC context to make the parameters visible for the whole thread and print them in the formatter of the logging statement.
log4j.appender.AppLog.layout.ConversionPattern = %d{ddMMyyyyHHmmss}|%X{feature}|%-5p|%t|%l|%X{actionId}|%m%n
But I wanted a more controlled solution. Note that in the example above the feature and actionId aren't printed throught the logging message, but this isn't a requirement.
I would do something like this:
public MyClass {
Logger log = new InterceptedLogger("com.foo.MyClass");
// ...
public void handleUserAction() {
log.info("Action detected !");
// ...
}
}
public InterceptedLogger extends Logger {
private static MyFramework myFrameWork = MyFramework.getInstance(); // or use an IoC to inject the instance for you...
public InterceptedLogger(String name) {
super(name);
}
public void info(Object message) {
if (isInfoEnable()) {
super.info( //
String.format( //
"%s#%s - %s", // this format may be configured externally
myFrameWork.getCurrentUser(), //
myFrameWork.getCurrentAction(), //
message //
));
}
}
// Override other methods as needed
}
I have enum say ErrorCodes that
public enum ErrorCodes {
INVALID_LOGIN(100),
INVALID_PASSWORD(101),
SESSION_EXPIRED(102) ...;
private int errorCode;
private ErrorCodes(int error){
this.errorCode = error;
} //setter and getter and other codes
}
now I check my exception error codes with this error codes. I don't want to write if this do this, if this do this. How I can solve this problem (writing 10+ if blocks)
Is there any design patter to that situation ?
Thanks
Either you do it with a if-statement or a switch, or you just implement the logic in question into the ErrorCode somehow.
In an OO fashion it all depends on how you want the application or system react to the error code. Lets say you just want it to output somekind of dialog:
public doSomethingWithError() {
ErrorCodes e = getError();
// the source of error, or originator, returns the enum
switch(e) {
case ErrorCodes.INVALID_LOGIN:
prompt('Invalid Login');
case ErrorCodes.INVALID_PASSWORD:
prompt('Invalid password');
// and so on
}
}
We could instead create an ErrorHandler class that does this instead:
// We'll implement this using OO instead
public doSomethingWithError() {
ErrorHandler e = getError();
// the originator now returns an ErrorHandler object instead
e.handleMessage();
}
// We will need the following abstract class:
public abstract class ErrorHandler {
// Lets say we have a prompter class that prompts the message
private Prompter prompter = new Prompter();
public final void handleMessage() {
String message = this.getMessage();
prompter.prompt(message);
}
// This needs to be implemented in subclasses because
// handleMessage() method is using it.
public abstract String getMessage();
}
// And you'll have the following implementations, e.g.
// for invalid logins:
public final class InvalidLoginHandler() {
public final String getMessage() {
return "Invalid login";
}
}
// E.g. for invalid password:
public final class InvalidPasswordHandler() {
public final String getMessage() {
return "Invalid password";
}
}
The former solution is easy to implement, but becomes difficult to maintain as the code grows larger. The latter solution is more complex, (aka. Template Method pattern following the Open-Closed Principle) but enables you to add more methods into the ErrorHandler when you need it (such as restoring resources or whatever). You can also implement this with the Strategy pattern.
You won't get away completely with the conditional statements, but in the latter the conditional is pushed to the part of the code where the error is originated. That way you won't have double maintenance on conditional statements both at the originator and the error handling code.
EDIT:
See this answer by Michael Borgwardt and this answer by oksayt for how to implement methods on Java Enums if you want to do that instead.
Java enums are very powerful and allow per-instance method implementations:
public enum ErrorCode {
INVALID_LOGIN {
public void handleError() {
// do something
}
},
INVALID_PASSWORD {
public void handleError() {
// do something else
}
},
SESSION_EXPIRED {
public void handleError() {
// do something else again
}
};
public abstract void handleError();
}
Then you can simply call errorCode.handleError();. However, it is questionable whether an ErrorCode enum is really the right place for that logic.
As pointed out by Spoike, using polymorphism to pick the right error handling method is an option. This approach basically defers the 10+ if blocks to the JVM's virtual method lookup, by defining a class hierarchy.
But before going for a full-blown class hierarchy, also consider using enum methods. This option works well if what you plan to do in each case is fairly similar.
For example, if you want to return a different error message for each ErrorCode, you can simply do this:
// Note singular name for enum
public enum ErrorCode {
INVALID_LOGIN(100, "Your login is invalid"),
INVALID_PASSWORD(101, "Your password is invalid"),
SESSION_EXPIRED(102, "Your session has expired");
private final int code;
private final String
private ErrorCode(int code, String message){
this.code = code;
this.message = message;
}
public String getMessage() {
return message;
}
}
Then your error handling code becomes just:
ErrorCode errorCode = getErrorCode();
prompt(errorCode.getMessage());
One drawback of this approach is that if you want to add additional cases, you'll need to modify the enum itself, whereas with a class hierarchy you can add new cases without modifying existing code.
I believe the best you can do is implementing the strategy pattern. This way you won't have to change existing classes when adding new enums but will still be able to extend them. (Open-Closed-Principle).
Search for Strategy Pattern and Open Closed Principle.
You can create a map of error codes(Integer) against enum types
Edit
In this solution, once the map is prepared, you can look up an error code in the map and thus will not require if..else look ups.
E.g.
Map<Integer, ErrorCodes> errorMap = new HashMap<Integer, ErrorCodes>();
for (ErrorCodes error : ErrorCodes.values()) {
errorMap.put(error.getCode(), error);
}
Now when you want to check an error code coming from your aplpication, all you need to do is,
ErrorCodes error = errorMap.get(erro_code_from_application);
Thus removing the need for all the if..else.
You just need to set up the map in a way that adding error codes doesn't require changes in other code. Preparation of the map is one time activity and can be linked to a database, property file etc during the initialization of your application
In my opinion there is nothing wrong with ErrorCodes as enums and a switch statement to dispatch error handling. Enums and switch fit together really well.
However, maybe you find the following insteresting (kind of over-design), see an Example
or "Double dispatching" on Wikipedia.
Assumed requirements:
Error-handling should be encapsulated in an own class
Error-handling should be replacable
Type safety: Whenever an error is added, you are forced to add error handling at each error-handler implementation. It is not possible to "forget" an error in one (of maybe many) switch statments.
The code:
//Inteface for type-safe error handler
interface ErrorHandler {
void handleInvalidLoginError(InvalidLoginError error);
void handleInvalidPasswordError(InvalidLoginError error);
//One method must be added for each kind error. No chance to "forget" one.
}
//The error hierachy
public class AbstractError(Exception) {
private int code;
abstract public void handle(ErrorHandler);
}
public class InvalidLoginError(AbstractError) {
private String additionalStuff;
public void handle(ErrorHandler handler) {
handler.handleInvalidLoginError(this);
}
public String getAdditionalStuff();
}
public class InvalidPasswordError(AbstractError) {
private int code;
public void handle(ErrorHandler handler) {
handler.handleInvalidPasswordError(this);
}
}
//Test class
public class Test {
public void test() {
//Create an error handler instance.
ErrorHandler handler = new LoggingErrorHandler();
try {
doSomething();//throws AbstractError
}
catch (AbstractError e) {
e.handle(handler);
}
}
}
I have the following situation where a client class executes different behavior based on the type of message it receives. I'm wondering if there is a better way of doing this since I don't like the instanceof and the if statements.
One thing I thought of doing was pulling the methods out of the client class and putting them into the messages. I would put a method like process() in the IMessage interface and then put the message specific behavior in each of the concrete message types. This would make the client simple because it would just call message.process() rather than checking types. However, the only problem with this is that the behavior contained in the conditionals has to do with operations on data contained within the Client class. Thus, if I did implement a process method in the concrete message classes I would have to pass it the client and I don't know if this really makes sense either.
public class Client {
messageReceived(IMessage message) {
if(message instanceof concreteMessageA) {
concreteMessageA msg = (concreteMessageA)message;
//do concreteMessageA operations
}
}
if (message instanceof concreteMessageB) {
concreteMessageb msg = (concreteMessageB)message;
//do concreteMessageB operations
}
}
The simple way to avoid instanceof testing is to dispatch polymorphicly; e.g.
public class Client {
void messageReceived(IMessage message) {
message.doOperations(this);
}
}
where each message class defines an appropriate doOperations(Client client) method.
EDIT: second solution which better matches the requirements.
An alternative that replaces a sequence of 'instanceof' tests with a switch statement is:
public class Client {
void messageReceived(IMessage message) {
switch (message.getMessageType()) {
case TYPE_A:
// process type A
break;
case TYPE_B:
...
}
}
}
Each IMessage class needs to define an int getMessageType() method to return the appropriate code. Enums work just as well ints, and are more more elegant, IMO.
One option here is a handler chain. You have a chain of handlers, each of which can handle a message (if applicable) and then consume it, meaning it won't be passed further down the chain. First you define the Handler interface:
public interface Handler {
void handle(IMessage msg);
}
And then the handler chain logic looks like:
List<Handler> handlers = //...
for (Handler h : handlers) {
if (!e.isConsumed()) h.handle(e);
}
Then each handler can decide to handle / consume an event:
public class MessageAHandler implements Handler {
public void handle(IMessage msg) {
if (msg instanceof MessageA) {
//process message
//consume event
msg.consume();
}
}
}
Of course, this doesn't get rid of the instanceofs - but it does mean you don't have a huge if-elseif-else-if-instanceof block, which can be unreadable
What type of message system are you using?
Many have options to add a filter to the handlers based on message header or content. If this is supported, you simply create a handler with a filter based on message type, then your code is nice and clean without the need for instanceof or checking type (since the messaging system already checked it for you).
I know you can do this in JMS or the OSGi event service.
Since you are using JMS, you can basically do the following to register your listeners. This will create a listener for each unique message type.
String filterMsg1 = "JMSType='messageType1'";
String filterMsg2 = "JMSType='messageType2'";
// Create a receiver using this filter
Receiver receiverType1 = session.createReceiver(queue, filterMsg1);
Receiver receiverType2 = session.createReceiver(queue, filterMsg2);
receiverType1.setMessageHandler(messageType1Handler);
receiverType2.setMessageHandler(messageType2Handler);
Now each handler will receive the specific message type only (no instanceof or if-then), assuming of course that the sender sets the type via calls to setJMSType() on the outgoing message.
This method is built into message, but you can of course create your own header property and filter on that instead as well.
//Message.java
abstract class Message{
public abstract void doOperations();
}
//MessageA.java
class MessageA extends Message{
public void doOperations(){
//do concreteMessageA operations ;
}
}
//MessageB.java
class MessageB extends Message {
public void doOperations(){
//do concreteMessageB operations
}
}
//MessageExample.java
class MessageExample{
public static void main(String[] args) {
doSmth(new MessageA());
}
public static void doSmth(Message message) {
message.doOperations() ;
}
}
A Java 8 solution that uses double dispatch. Doesn't get rid of instanceof completely but does only require one check per message instead of an if-elseif chain.
public interface Message extends Consumer<Consumer<Message>> {};
public interface MessageA extends Message {
#Override
default void accept(Consumer<Message> consumer) {
if(consumer instanceof MessageAReceiver){
((MessageAReceiver)consumer).accept(this);
} else {
Message.super.accept(this);
}
}
}
public interface MessageAReceiver extends Consumer<Message>{
void accept(MessageA message);
}
With JMS 2.0 you can use:
consumer.receiveBody(String.class)
For more information you can refer here: