How to make this code DRYer - java

So I have a generated class (PartnerConnection) that provides DML operations to the SalesForce cloud platform. We were having issues where our long running integration process was failing due to connection issues with either SalesForce or the system running the code.
In order to solve this issue, I extended the PartnerConnection class with what I name an AdvancedPartnerConnection. The AdvancedPartnerConnection just overrides the methods of the PartnerConnection and wraps them with try/catch/retry logic.
#Override
public QueryResult query(String queryString) throws ConnectionException{
int attempt = 0;
ConnectionException lastException = null;
while(true){
if(attempt < maxAttempts){ //maxAttempts constant
if(lastException != null){
try {
//exponentially increase wait times
Long sleepTime =(long) Math.pow(sleepBase, attempt) * 300;
Thread.sleep(sleepTime);
} catch (InterruptedException e1) {
// something bad has happen, throw the connection exception
throw lastException;
}
}
attempt ++;
try{
//call super class method
return super.query(queryString);
}catch(ConnectionException e){
lastException = e;
}
}else{
throw lastException;
}
}
}
I've implemented this for a handful of the super class methods and the only difference is the method being called and its' parameters. It has become a real pain if I decided to change any of the retry logic as I want it to be consistent across all methods.
Does anyone have a way I could extract the retry logic into a separate class or method and maybe pass in the function call? I've done stuff like this in .NET but I'm not sure how to do it in java.

You basically want to capture all calls to all object methods and apply some logic to all of them.
You could create a Proxy and retry in the handler invoke method.
With this approach based on the method signature you decide what to do.
Another approaches could use AspectJ or any other AOP framework, but your use case is very simple to add that kind of dependencies, IMO.
If the class which you want to add some behaviour is not yours then this solution might not be the most elegant. But if you are willing to sacrifice some elegance to gain maintainability (since you are not replicating code) then you could:
class NotYourClass {
public void voidMethod() {}
public int intMethod(int n) { return 0; }
}
To create a proxy you must create an interface with all the methods of the class. This is the crappy part, but this do not add any dependency to your application.
interface YourInterface {
public void voidMethod();
public int intMethod(int n);
}
Next thing you need is an InvocationHandler that will contain the behavior.
class YourInvocationHandler implements InvocationHandler {
private final NotYourClass target;
public YourInvocationHandler(NotYourClass target) {
this.target = target;
}
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
try {
// Here you must look to the methods that are the ones that you want.
return method..invoke(target, args);
} catch (Exception e) {
// Retry?
method.invoke(target, args);
}
}
}
Please bear in mind that this is from the top of my head. But should be something along those lines.
If creating that interface is something unnacceptable for you then you can look at some AOP frameworks.

Related

How to test behavior of parametrized constructor with JMockit? (New with JMockit)

I have a factory class which constructor takes two parameter. Depending on that parameters the factory creates four different types of classes or throws IllegalArgumentExceptions in case of invalid arguments.
First I need to test if the appropirate class is created depending on the given parameters.
Second I need to verify the correct Exception in case of invalid parameters.
For testing the correct class is build in the factory I can fake the expected class and verify their instantiation.
But I don't know how to deal with #Tested to set up specific parameters in the constructor.
I coudn't find any usable hint neither in the JMockit documentation nor by searching the internet.
Below is a sample factory class and a sample of a class created by the factory (the others are similar).
public class WorkerFactory {
private Worker worker;
public WorkerFactory(final String type, final String subtype) {
if(type == null) throw new IllegalArgumentException("type");
if(subtype == null) throw new IllegalArgumentException("subtype");
if(type.equals("One")) {
if(subtype.equals("A")) worker = new One_A();
else if(subtype.equals("B")) worker = new One_B();
else throw new IllegalArgumentException("subtype");
}
else if(type.equals("Two")) {
if(subtype.equals("A")) worker = new Two_A();
else if(subtype.equals("B")) worker = new Two_B();
else throw new IllegalArgumentException("subtype");
}
else throw new IllegalArgumentException("type");
}
public Worker getWorker() { return worker; }
}
public interface Worker {
public void doWork();
}
public class One_A implements Worker {
public void doWork() {
System.out.println(getClass().getName());
}
}
And a very stupid skeleton for the requiered test BUT without using JMockit.
package application;
import org.junit.Test;
public class WorkerFactoryTest {
WorkerFactory cut;
#Test
public final void testWorkerFactory() {
cut = new WorkerFactory("One", "A");
cut.getWorker().doWork();
cut = new WorkerFactory("One", "B");
cut.getWorker().doWork();
cut = new WorkerFactory("Two", "A");
cut.getWorker().doWork();
cut = new WorkerFactory("Two", "A");
cut.getWorker().doWork();
}
#Test
public final void testWorkerFactoryExceptions() {
try {
cut = new WorkerFactory("Three", "C");
} catch (Exception e) {
e.printStackTrace();
}
try {
cut = new WorkerFactory("One", "C");
} catch (Exception e) {
e.printStackTrace();
}
}
}
``
EDIT (2020.07.02):
The assertThrows(..) from JUnit is one way to verify exceptions. But I use still the old style try/catch variant encapsulated in functions like verifyNoException(errorMessage) with a fail(...) if i caught one or verifyXyzException(expectedExceptionMessage) with a fail(...) if I cought none. This gives me a better control over the exceptions I catch by even a good readability. A time ago i read about some drawbacks about assertThrows over the old fashin style but I can't remeber what they are.
Putting constructor logic in an init(..) method as suggested by JMockit is what I do indeed (the given example did not for simplification). But I still want to test the constructor and not the private initializer method(s). Also I prefere a design where a object gets fully initialized by constructor parameters because I don't like the (boring and ugly) setter calls.
And verifying the parameters passed in is even a good one in my opinion.
The #Tested annotation is useful in 90% of scenarios - empty constructor or constructors where all the args can be passed mocks via #Injectable. That's not the scenario you are in due to you trying to test the permutations through your constructor.
As an aside, JMockit is poking you and saying you might want to reconsider your design. For example, shift that constructor logic to an "init(..)" method (call it whatever) and you'd find things easier to work with, and likely a better overall design. Likewise, constructors-throwing-exceptions is poor design, which the init(..) would get you away from. But I digress...
Your testWorkerFactory(..) is fine as-is. There's no easy way to do permutations of constructor arguments, so what you've got is fine. Brute force is fine. Everything doesn't have to be JMockit, JUnit is still OK.
For testWorkerFactoryExceptions, I'd make use of assertThrows(..) as it is much cleaner and guarantees that you receive the expected throw.

Exception flow control

I use exceptions to flow control a lot, but I have a strange feeling that I am doing something wrong. Is it a good practice to write something like code shown bellow?
public static void main(String[] args)
{
try
{
methodA();
}
catch (Exception ex)
{
handleException(ex);
}
}
public static methodA()
{
methodB();
}
public static methodB()
{
if(someConditionIsNotMet)
{
throw new RuntimeException("Some Condition Is Not Met");
}
}
I use exceptions to flow control a lot
Throwing specific and functional exceptions to indicate a functional issue during the workflow is not bad itself.
It is not the single way to do it but it is a valid way.
Another way relies on methods that returns boolean and testing the returned value.
Personally, I don't use this way as I found it rather verbose, error-prone (we have not to forget to test the returned boolean) and less expressive (it has only two values: true and false) than an exception (it may have as many as required).
Suppose that method B has to check something and that if the check fails the processing should be stopped and the client notified of the issue, it would be totally valid to use exceptions for this purpose.
Now, it would make more sense to make the exception a specific exception rather than Exception.
Otherwise how the client could interpret the exception meaning ?
The exception could be a workflow exception but it could be also any exception thrown at runtime for another reason such as a NullPointerException.
You want to handle workflow exceptions in a specific way while you will not apply a specific processing to other thrown exceptions.
For example you could write something as :
public static methodA()
{
methodB();
}
public static methodB(){
if (!expectedDataFound()){
throw new DataNotFoundException("data xxx was not found");
}
if (!hasRights()){
throw new PermissionException("user xxx has not the rights for yyy");
}
}
Then from the client side, you have two ways.
Catching each exception individually or catching them in a common way (that is possible only if they make part of the same hierarchy).
Catching each exception individually :
public static void main(String[] args)
{
try
{
methodA();
}
catch (DataNotFoundException ex)
{
handleDataNotFoundException(ex);
}
catch (PermissionException ex)
{
handlePermissionException(ex);
}
}
Catching exception globally:
public static void main(String[] args)
{
try
{
methodA();
}
catch (WorkflowException ex)
{
handleWorkflowException(ex);
}
}
I think you are too harsh on yourself with saying that you "use exceptions to control flow". It is an antipattern to use exceptions for control flow, but in your example you do not.
Let's say that you have a method that sets the age for the user, and of course if the caller provided negative number, you should not complete the action. So a very reasonable way to ensure that, would be:
public void setAge(int age) {
if(age <0) {
throw new InvalidArgumentException("Age has to be zero or positive number");
}
}
If you prefer not to use exceptions maybe you can use features of the language such as Optionals or create response structure that handles both success and errors. For example, lets say you have a method that retrieves employees
public EmployeesOverview getEmployees() { ... }
Your response class could look like this:
public class EmployeesOverview {
private Ok ok;
private Error error;
class Ok {
private Set<Employee> employees;
}
class Error {
private String errorMessage;
}
}
So without throwing exception your method will provide clients with results or if there is a problem, the client will be informed about it.
I would separate flow control and exception handling. Flow control is meant for making sure statements are executed in correct sequence and under correct conditions. This must be determined at design time. Exception handling is meant to handle unforeseen situations at run time. Exceptions are almost always due to external factors: time outs, no disk space, data errors...
Just my two cents.

Is it a good idea to use reflections in a Web application?

I have developed below code with the intention to remove if else conditions so that code cyclomatic complexity should be less.
For this I have used reflection api and wrote method which takes condition as an argument and called respective method on the condition name basis.
This works fine, I want to know is it a good idea to use reflection (This code) in web application, so that I am free from checking conditions.
For example in below code we have different method with prefix state ex: stateSUBMIT, stateWithdraw etc.
we can call stateSUBMIT method by passing only "SUBMIT".
public class Participate {
public String execute(String methodName) {
String st = null;
try {
Method method = this.getClass().getDeclaredMethod(
"state" + methodName);
method.invoke(this);
} catch (Exception e) {
e.printStackTrace();
}
return st;
}
public void stateSUBMIT() {
System.out.println("in SUBMIT");
}
public void stateWithdraw() {
System.out.println("in Withdraw");
}
public void state() {
System.out.println("in state ");
}
public void statenull() {
System.out.println("in null ");
}
public static void main(String[] args) {
Participate p = new Participate();
p.execute("SUBMIT");
}
}
This is valid code, but can be achieved without reflections.
Step One: Define an interface
public interface Command {
public void execute();
}
Step Two: Create Concrete Implementations
public class StateCommand implements Command {
public void execute() {
// Your code.
}
}
Step Three: Add a collection of these to your original class
private Map<String, Command> commands;
Step Four: Populate
public MyClass() {
commands = new HashMap<String, Command>();
commands.put("state", new StateCommand());
}
Get that class and execute
public String callMethod(String name) {
Command command = commands.get(name);
if(command != null) {
command.execute();
}
}
This is just a relatively simple alternative to using reflections, which should be considered as a last resort.
I would avoid it. There are better alternatives. You could pick one of all the numerous web frameworks or you could code something similar without reflection. For example, use a HashMap from the action (SUBMIT, ...) to an object that implements an interface. That way you can call a method with parameters without reflection, which is slow and which provides no compile-time validations. This is not a recommendation (go with a framework!), but it is a better way of doing what you are doing right now.
Your implementation is beneficial in case if you are doing for making this Generic approach for all other other classes in your project.Its good if you are having re usability of this in many other scenarios.
But if its only for specific implementation which is not generalized then there are many simple ways to do this job, because if you will use java reflections than there is some amount of time complexity involved which is comparatively less if you do it without using reflectns.

Double checked locking in modern JVMs

I have a class that might throw any run-time exceptions during initialization. I want the class to be a singleton since the cost of keeping several objects in memory is high. I am using that class in another class.
My use case is as follows:
I have to use a single instance of Controller.
Each instance of Parent must use the same Controller instance.
Controller
constructor might throw exceptions.
If instantiation fails, I should
retry to instantiate after sometime.
So I check if my Controller instance is null when I try to do a "get" on the Controller, if yes, I try to instantiate it again.
Following is my code:
class Parent
{
private static volatile Controller controller;
private static final Object lock = new Object();
static
{
try
{
controller = new Controller();
}
catch(Exception ex)
{
controller = null;
}
}
private Controller getController() throws ControllerInstantiationException
{
if(controller == null)
{
synchronized(lock)
{
if(controller == null)
{
try
{
controller = new Controller();
}
catch(Exception ex)
{
controller = null;
throw new ControllerInstatntationException(ex);
}
}
}
}
return controller;
}
//other methods that uses getController()
}
My question is, is this code broken? I read somewhere that the above code would be a problem in JVM 1.4 or earlier. Can you provide references/solutions? Please note that I am asking this question because there is a lot of confusion regarding this topic in the internet.
Thanks.
I believe it's not broken, cause of volatile declaration. But imho better to avoid code like this. There is no guarantee, that this code will work with Java 8 for example. There are another way to create lazy singleton. I always (almost) use this method. First time faced with it in Java Concurrency in Practice book.
public class Singleton {
private Singleton() { }
private static class SingletonHolder {
public static final Singleton instance = new Singleton();
}
public static Singleton getInstance() {
return SingletonHolder.instance;
}
}
I don't know what you are doing in your code, it's hard to say, how to tweak it. The most straightforward way, simply use synchronize method. Do you seriously want to receive some performance benefit using double-check-locking ? Is there bottle-neck in synch method ?
The only thing which is broken is to make the example far more complicated than it needs to be.
All you need is an enum
// a simple lazy loaded, thread safe singleton.
enum Controller {
INSTANCE
}
Using an AtomicBoolean (much like I suggested here) would be safer and allows for repeat attempts at instantiation on failure.
public static class ControllerFactory {
// AtomicBolean defaults to the value false.
private static final AtomicBoolean creatingController = new AtomicBoolean();
private static volatile Controller controller = null;
// NB: This can return null if the Controller fails to instantiate or is in the process of instantiation by another thread.
public static Controller getController() throws ControllerInstantiationException {
if (controller == null) {
// Stop another thread creating it while I do.
if (creatingController.compareAndSet(false, true)) {
try {
// Can fail.
controller = new Controller();
} catch (Exception ex) {
// Failed init. Leave it at null so we try again next time.
controller = null;
throw new ControllerInstantiationException(ex);
} finally {
// Not initialising any more.
creatingController.set(false);
}
} else {
// Already in progress.
throw new ControllerInstantiationException("Controller creation in progress by another thread.");
}
}
return controller;
}
public static class ControllerInstantiationException extends Exception {
final Exception cause;
public ControllerInstantiationException(Exception cause) {
this.cause = cause;
}
public ControllerInstantiationException(String cause) {
this.cause = new Exception(cause);
}
}
public static class Controller {
private Controller() {
}
}
}
Yes, it is guaranteed to work by the Java Memory Model on modern JVMs. See the section Under the new Java Memory Model in The "Double-Checked Locking is Broken" Declaration.
As other answers have pointed out, there are simpler singleton patterns, using Holder classes or enums. However, in cases like yours, where you want to allow for trying to reinitialize several times if the first try fails, I believe that double-checked locking with a volatile instance variable is fine.
It is not an answer to your question but this famous article on Double-Checked Locking is Broken explains well as to why it is broken for java 1.4 or earlier version.

Eclipse supress compiler error - Is there a possible work around?

Here's the scenario:
I have a program that contains an annotation that I built out in my eclipse project, it's called 'flag'.
The 'flag' annotation has an 'id' element
I have a method in my class called 'connect' that establishes a socket connection.
I annotate the connect method by placing the 'flag' annotation before it and give it an 'id'
public class Foo {
#flag(id = 'slowConnection')
public boolean connect() {
// connect logic here...
}
}
Now, what I ultimately want is something like the following
public class Foo {
#flag(id = 'slowConnection')
public boolean connect() {
// connect logic here...
}
#flag(id = 'mediumConnection')
public boolean connect() {
// medium connection logic here
}
#flag(id = 'fastConnection')
public boolean connect() {
// fast connection logic here
}
}
Allow me to elaborate here. My objective is to be able to only include the correct 'connect' method at compile time based on an input parameter to the class. Method overloading is a similar way to do this, albeit I don't want to change the method signature. I'm also aware that inheritance would be a way to do this. Eclipse (rightly so) complains when I have the above code, saying that there's a duplicate method. Is there anyway that I could proceed with the above in Eclipse before I compile the program as I will perform some logic to strip out all but one of the 'connect' methods before the program is compiled? Is there a way to automatically disable auto-compilation in eclipse? Any tips or pointers would be helpful.
You move the connection logic to a separate interface and then use the factory pattern to generate the appropriate connection:
public interface IFoo {
void connect();
}
final class SlowFoo implements IFoo {
//Implementation for slow connections
}
final class MediumFoo implements IFoo {
//Implementation for medium connections
}
final class FastFoo implements IFoo {
//Implementation for fast connections
}
If the classes share common code, you should consider introducing a base class like FooBase.
The factory could then look like this:
public final class FooFactory {
public IFoo create() {
if (Connection.speed < 100) //Fictive value
return new SlowFoo();
if (Connection.speed < 1000) //Fictive value
return new MediumFoo();
return new FastFoo();
}
}
Messing around with the source code before compilation is not a good idea IMHO.

Categories

Resources