I have 2 repositories classes:
public class ResponseRepository implements IRoutingResponseRepository {
private final String baselineFileName;
#Inject
#Singleton
public ResponseRepository(#Named("baseline_file") String baselineFileName) {
this.baselineFileName = baselineFileName;
}
#Override
public E2EResult getBaseLine() {
E2EResult e2EResult = null;
ObjectMapper mapper = new ObjectMapper();
try
{
e2EResult = mapper.readValue(new File(baselineFileName), E2EResult.class);
} catch (JsonGenerationException e)
{
e.printStackTrace();
} catch (JsonMappingException e)
{
e.printStackTrace();
} catch (IOException e)
{
e.printStackTrace();
}
return e2EResult;
}
}
and
public class StatsRepository implements IRoutingResponseRepository {
private final String baselineFileName;
#Inject
#Singleton
public StatsRepository(#Named("stats_file") String baselineFileName) {
this.baselineFileName = baselineFileName;
}
#Override
public StatsObj getStats() {
StatsObj statsObj = null;
ObjectMapper mapper = new ObjectMapper();
try
{
statsObj = mapper.readValue(new File(baselineFileName), StatsObj.class);
} catch (JsonGenerationException e)
{
e.printStackTrace();
} catch (JsonMappingException e)
{
e.printStackTrace();
} catch (IOException e)
{
e.printStackTrace();
}
return statsObj;
}
}
how can I refactor the common code to be generic one?
and also I want guice to use fileName = E2EResult.csv when <E2EResult> and fileName = StatsObj.csv when <StatsObj>
I have tried:
but I wrote the generics incorrectly. It shows an error.
And also i'm not sure how to let guice inject different fileName
public interface IFileHandler<T> {
T getContent();
}
and
public class JsonFileHandler implements IFileHandler<T> {
String fileName;
#Inject
public JsonFileHandler(String file) {
this.fileName = file;
//Constants.RESULTS_BASELINE_FILE
}
public <T> T getContent() {
T t = null;
ObjectMapper mapper = new ObjectMapper();
try {
t = mapper.readValue(new File(fileName), T.class);
} catch (JsonGenerationException e) {
e.printStackTrace();
} catch (JsonMappingException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return t;
}
}
For the type variable part, it would be, with this interface:
public interface IFileHandler<T> {
T getContent();
}
this implementing class declaration and method signature:
class JsonFileHandler<T> implements IFileHandler<T> {
public T getContent() {
T t = null;
// ...
return t;
}
}
Related
I have this method sendParameterValueAsMQTTMessage() which I use to publish message via MQTT on a specific topic. I am using try catch two times after another (not nested) but it still seems somewhat ugly and overcrowding the method. I read an article on clean code where Uncle Bob talks about extracting the body of try catch but I seem to not grasp it quite well or at least not in my case.
How could I get rid of the try catch in my method by extracting it outside?
public void sendParameterValueAsMQTTMessage() {
String payload = null;
try {
payload = convertToJSONString("range", String.valueOf(range));
} catch (JSONException e) {
this.logger.log(Level.ERROR, e);
}
MQTTMessage message = new MQTTMessage(MQTTTopics.RANGE_TOPIC,payload,0);
try {
this.client.publish(message);
Thread.sleep(3000);
} catch (Exception e) {
this.logger.log(Level.ERROR, e);
}
}
there are multiple different problems with provided code, here is how I'd refactor it:
public void sendParameterValueAsMQTTMessage() {
final String payload = tryGetPayloadAsJson();
if (payload != null) {
trySendPayloadViaMQTT(payload);
}
}
private String tryGetPayloadAsJson() {
try {
return convertToJSONString("range", String.valueOf(range));
} catch (JSONException e) {
this.logger.log(Level.ERROR, e);
}
return null;
}
private void trySendPayloadViaMQTT(final String payload) {
try {
final MQTTMessage message = new MQTTMessage(MQTTTopics.RANGE_TOPIC, payload, 0);
this.client.publish(message);
Thread.sleep(3000);
} catch (Exception e) {
this.logger.log(Level.ERROR, e);
}
}
one thing which might be improved here based on Uncle Bob's advice is to actually move try/catch outside of trySendPayloadViaMQTT, like this:
public void sendParameterValueAsMQTTMessage() {
final String payload = tryGetPayloadAsJson();
if (payload != null) {
trySendPayloadViaMQTT(payload);
}
}
private String tryGetPayloadAsJson() {
try {
return convertToJSONString("range", String.valueOf(range));
} catch (JSONException e) {
this.logger.log(Level.ERROR, e);
}
return null;
}
private void trySendPayloadViaMQTT(final String payload) {
try {
sendPayloadViaMQTT(payload);
} catch (Exception e) {
this.logger.log(Level.ERROR, e);
}
}
private void sendPayloadViaMQTT(final String payload) {
final MQTTMessage message = new MQTTMessage(MQTTTopics.RANGE_TOPIC, payload, 0);
this.client.publish(message);
Thread.sleep(3000);
}
you can put all of your code in just one try block and set multiple catches, when ever an exception be happened, the catch that is revelated to it will be execute, like:
try{
int a[]=new int[5];
a[5]=30/0;
}
catch(ArithmeticException e)
{
System.out.println("Arithmetic Exception occurs");
}
catch(ArrayIndexOutOfBoundsException e)
{
System.out.println("ArrayIndexOutOfBounds Exception occurs");
}
You can use single general catch for both possible exceptions inside the method as following:
public void sendParameterValueAsMQTTMessage() {
String payload = null;
try {
payload = convertToJSONString("range", String.valueOf(range));
MQTTMessage message = new MQTTMessage(MQTTTopics.RANGE_TOPIC,payload,0);
this.client.publish(message);
Thread.sleep(3000);
} catch (Exception e) {
this.logger.log(Level.ERROR, e);
}
}
public void sendParameterValueAsMQTTMessage() {
String payload = null;
try {
payload = convertToJSONString("range", String.valueOf(range));
} catch (JSONException e) {
this.logger.log(Level.ERROR, e);
}
MQTTMessage message = new MQTTMessage(MQTTTopics.RANGE_TOPIC,payload,0);
publishMessage(message); //extracted in a new method
}
public void publishMessage(MQTTMessage message){
try {
this.client.publish(message);
Thread.sleep(3000);
} catch (Exception e) {
this.logger.log(Level.ERROR, e);
}
}
New to java 8, I would like to optimise my code bellow:
public Response create() {
try{
...
} catch (Exception e) {
codeA;
} finally {
codeB;
}
}
public Response update() {
try{
...
} catch (Exception e) {
codeA;
} finally {
codeB;
}
}
I have a lot of methods using this same way to catch exceptions and do the same finally, is that possible to replace the bellow common code by a method in java 8? So that I could optimise all my methods who use this common code.
} catch (Exception e) {
codeA;
} finally {
codeB;
}
Depends what you do in the .... You could do something like this:
private Response method(Supplier<Response> supplier) {
try{
return supplier.get();
} catch (Exception e) {
codeA;
} finally {
codeB;
}
}
and invoke like:
public Response create() { return method(() -> { ... for create }); }
public Response update() { return method(() -> { ... for update }); }
You could wrap your payload and put it to the separate method. One thing; what do you expect to return on exception catch. This time this is null, but probably you could provide default value.
public static <T> T execute(Supplier<T> payload) {
try {
return payload.get();
} catch(Exception e) {
// code A
return null;
} finally {
// code B
}
}
Client code could look like this:
public Response create() {
return execute(() -> new CreateResponse());
}
public Response update() {
return execute(() -> new UpdateResponse());
}
This could be a generic solution.
//here describe supplier which can throw exceptions
#FunctionalInterface
public interface ThrowingSupplier<T> {
T get() throws Exception;
}
// The wrapper
private <T> T callMethod(ThrowingSupplier<T> supplier) {
try {
return supplier.get();
} catch (Exception e) {
//code A
}finally {
// code B
}
}
I have a similar problem as asked here - How to disable Redis Caching at run time if redis connection failed. My application is using #Cacheable at the service layer for most of the database/static resources call.
Cache is backed by Couchbase and whenever application fails to connect Couchbase node application goes down. Which is what we are not expecting, we expect data should be served from the source system whenever connection failed.
We tried implementing CacheErrorHandler but it does not work as expected because we want to execute the actual method which is making a service call and return the response rather than logging the Cache fail, basically bypassing the cache and as soon as the Couchbase node is up or connection established get the data from cache.
Any idea how we can achieve it?
Thanks #Daniel Bickler for the suggestion, below is the implementation I written referring #John Blum answer.
CouchbaseCustomCacheManager:
import java.util.Map;
import org.springframework.cache.Cache;
import com.couchbase.client.spring.cache.CacheBuilder;
import com.couchbase.client.spring.cache.CouchbaseCacheManager;
public class CouchbaseCustomCacheManager extends CouchbaseCacheManager {
public CouchbaseCustomCacheManager(
final Map<String, CacheBuilder> initialCaches) {
super(initialCaches);
}
#Override
public Cache getCache(String name) {
return new CouchbaseCacheWrapper(super.getCache(name));
}
protected static class CouchbaseCacheWrapper implements Cache {
private final Cache delegate;
public CouchbaseCacheWrapper(Cache couchbaseCache) {
this.delegate = couchbaseCache;
}
#Override
public String getName() {
try {
return delegate.getName();
} catch (Exception e) {
return null;
}
}
#Override
public Object getNativeCache() {
try {
return delegate.getNativeCache();
} catch (Exception e) {
return null;
}
}
#Override
public ValueWrapper get(Object key) {
try {
return delegate.get(key);
} catch (Exception e) {
return null;
}
}
#Override
public <T> T get(Object key, Class<T> type) {
try {
return delegate.get(key, type);
} catch (Exception e) {
return null;
}
}
#Override
public void put(Object key, Object value) {
try {
delegate.put(key, value);
} catch (Exception e) {
try {
handleErrors(e);
} catch (Exception e1) {
}
}
}
#Override
public ValueWrapper putIfAbsent(Object key, Object value) {
try {
return delegate.putIfAbsent(key, value);
} catch (Exception e) {
return null;
}
}
#Override
public void evict(Object key) {
try {
delegate.evict(key);
} catch (Exception e) {
try {
handleErrors(e);
} catch (Exception e1) {
}
}
}
#Override
public void clear() {
try {
delegate.clear();
} catch (Exception e) {
try {
handleErrors(e);
} catch (Exception e1) {
}
}
}
protected <T> T handleErrors(Exception e) throws Exception {
if (e instanceof Exception) {
return null;
} else {
throw e;
}
}
}
}
And used it as:
#Bean
public CacheManager cacheManager() {
final Map<String, CacheBuilder> cache = new HashMap<>();
for (final String appCache : "127.0.0.1,127.0.0.2,127.0.0.3".split(",")) {
cache.put(appCache, CacheBuilder.newInstance(CouchbaseCluster.create().openBucket(
"default", "")));
}
return new CouchbaseCustomCacheManager(cache);
}
I'm trying to consolidate 2 methods into 1, because they handle exceptions the same way. I know in C# you can pass functions/actions as parameters into other functions. I tried creating a generic method to invoke a function, but can't seem to figure it out.
public String getTheStuff(String client) {
try {
return extService.getProduct(client);
} catch (UIException e) {
notHealthy();
} catch (HostException e) {
notHealthy();
} catch (Exception e) {
Throwables.propagate(e);
}
}
public CustomType getsomeMoreStuff(String source, int offset) {
try {
return extService.getMetrics(source, offset);
} catch (UIException e) {
notHealthy();
} catch (HostException e) {
notHealthy();
} catch (Exception e) {
Throwables.propagate(e);
}
}
What I'm looking for is something like
public T invokeExtService(Function functionToInvoke, Parameters[] params){
try {
return functionToInvoke.Invoke(params);
} catch (UIException e) {
notHealthy();
} catch (HostException e) {
notHealthy();
} catch (Exception e) {
Throwables.propagate(e);
}
}
As #LouisWasserman said, this would be much nicer in Java 8, but how about something like this (untested):
public <T> T invoke(Callable<T> function) {
try {
return function.call();
} catch (UIException e) {
notHealthy();
} catch (HostException e) {
notHealthy();
} catch (Exception e) {
Throwables.propagate(e);
}
}
public String getTheStuff(final String client) {
return invoke(new Callable<String>() {
#Override
public String call() {
return extService.getProduct(client);
}
});
}
public CustomType getsomeMoreStuff(final String source, final int offset) {
return invoke(new Callable<CustomType>() {
#Override
public CustomType call() {
return extService.getMetrics(source, offset);
}
});
}
To be honest, I'm not sure how worthwhile this is considering how short your methods are (and they could be even shorter with multi-catch).
There're some library classes that although implement Serializable, fail to serialize correctly. I can't fix them, but I can extend ObjectOutputStream and ObjectInputStream for some workaround.
I want my ObjectOutputStream to write additional data for each instance of class A and ObjectInputStream to read and apply that data after A is deserialized.
Currently I have a mid-workaround that requires explicit additional calls to writeObject() and readObject(). I'd prefer to manage without these calls.
Uncomment /* */ blocks to see how it works.
import java.io.*;
import java.lang.reflect.Field;
import java.util.*;
import org.junit.Test;
import static org.junit.Assert.*;
public class CloneSerializableTest2 {
// library classes
public static class A implements Serializable {
public transient String s1;
}
public static class MyA extends A {
public String s2;
}
/*
private static class AHolder implements Serializable {
private static final Field s1Fld;
static {
try {
s1Fld = A.class.getDeclaredField("s1");
s1Fld.setAccessible(true);
} catch (NoSuchFieldException e) {
throw new RuntimeException("Unexpected error", e);
}
}
private String s1;
private A a;
public AHolder(A m) {
this.a = m;
try {
s1 = (String)s1Fld.get(m);
} catch (IllegalAccessException e) {
throw new RuntimeException("Unexpected error", e);
}
}
public void restoreA() {
try {
s1Fld.set(a, s1);
} catch (IllegalAccessException e) {
throw new RuntimeException("Unexpected error", e);
}
}
}
*/
#SuppressWarnings("unchecked")
public static <T> T cloneSerializable(T o) {
try {
/*
final List<AHolder> accumSrc = new ArrayList<AHolder>();
*/
ByteArrayOutputStream bout = new ByteArrayOutputStream();
ObjectOutputStream out = new ObjectOutputStream(bout)
/*
{
{
enableReplaceObject(true);
}
#Override
protected Object replaceObject(Object obj) throws IOException
{
if (obj instanceof A) {
accumSrc.add(new AHolder((A)obj));
}
return super.replaceObject(obj);
}
}
*/
;
out.writeObject(o);
/*
out.writeObject(accumSrc);
*/
out.close();
ByteArrayInputStream bin = new ByteArrayInputStream(bout.toByteArray());
ObjectInputStream in = new ObjectInputStream(bin);
Object copy = in.readObject();
/*
List<AHolder> accumDst = (List<AHolder>)in.readObject();
for (AHolder r : accumDst) {
r.restoreA();
}
*/
in.close();
return (T)copy;
} catch (IOException e) {
throw new RuntimeException("Unexpected error", e);
} catch (ClassNotFoundException e) {
throw new RuntimeException("Unexpected error", e);
}
}
#Test
public void testIt() throws Exception {
try {
MyA m1 = new MyA();
m1.s1 = "a";
m1.s2 = "b";
m1 = cloneSerializable(m1);
assertEquals("a", m1.s1);
assertEquals("b", m1.s2);
} catch (Exception e) {
e.printStackTrace();
throw e;
}
}
}
Answering to myself
import java.io.*;
import java.lang.reflect.Field;
import org.junit.Test;
import static org.junit.Assert.*;
public class CloneSerializableTest2 {
// library classes
public static class A implements Serializable {
public transient String s1;
}
public static class MyA extends A {
public String s2;
}
private static class AHolder implements Serializable, Externalizable {
private static final Field s1Fld;
static {
try {
s1Fld = A.class.getDeclaredField("s1");
s1Fld.setAccessible(true);
} catch (NoSuchFieldException e) {
throw new RuntimeException("Unexpected error", e);
}
}
private String s1;
private A a;
#SuppressWarnings("unused")
public AHolder() {
}
public AHolder(A m) {
this.a = m;
try {
s1 = (String)s1Fld.get(m);
} catch (IllegalAccessException e) {
throw new RuntimeException("Unexpected error", e);
}
}
private Object readResolve() {
try {
s1Fld.set(a, s1);
} catch (IllegalAccessException e) {
throw new RuntimeException("Unexpected error", e);
}
return a;
}
#Override
public void writeExternal(ObjectOutput out) throws IOException {
out.writeObject(s1);
ObjectOutputStream out2 = ((ObjectOutputStream)out);
out2.writeUnshared(a);
}
#Override
public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
s1 = (String)in.readObject();
a = (A)in.readObject();
}
}
#SuppressWarnings("unchecked")
public static <T> T cloneSerializable(T o) {
try {
ByteArrayOutputStream bout = new ByteArrayOutputStream();
ObjectOutputStream out = new ObjectOutputStream(bout)
{
{
enableReplaceObject(true);
}
#Override
protected Object replaceObject(Object obj) throws IOException
{
if (obj instanceof A) {
obj = new AHolder((A) obj);
} else if (obj instanceof AHolder) {
obj = ((AHolder)obj).a;
}
return super.replaceObject(obj);
}
};
out.writeObject(o);
out.close();
ByteArrayInputStream bin = new ByteArrayInputStream(bout.toByteArray());
ObjectInputStream in = new ObjectInputStream(bin);
Object copy = in.readObject();
in.close();
return (T)copy;
} catch (IOException e) {
throw new RuntimeException("Unexpected error", e);
} catch (ClassNotFoundException e) {
throw new RuntimeException("Unexpected error", e);
}
}
#Test
public void testIt() throws Exception {
try {
MyA m1 = new MyA();
m1.s1 = "a";
m1.s2 = "b";
m1 = cloneSerializable(m1);
assertEquals("a", m1.s1);
assertEquals("b", m1.s2);
} catch (Exception e) {
e.printStackTrace();
throw e;
}
}
}