calling methods that do not exist yet java - java

I am trying to make automated error handling in java. Some one else could call my error handling method and it handles the errors for them. I am attempting to have it so if the class calling my method had a close() method I could call it and it would close everything preventing resource leaks. I tried something like this:
public void logError(Error e, Object obj){
obj.close();
}
The only problem is this will not run because object by default does not have a close() method. I could create my own object and have their class extend it but it would not work if they wanted to extend a different class.

You need an interface:
interface Closeable {
public void close();
}
Otherwise you could inspect the Object via reflection.

I think you have a design issue if you're closing resources in a logging method. As others have mentioned, use an interface and handle closing the resource elsewhere.
If you really want to proceed with this approach, you need to use reflection. The invoke call below will throw some exceptions that you'll need to catch.
public void logError(Error e, Object obj)
{
Method closeMethod = obj.getClass().getMethod("close", null)
if (closeMethod != null)
closeMethod.invoke(obj, null);

You could use the following:
public void logError(Error e, Closeable obj) {
//do your logging
obj.close();
}
public void logError(Error e, Object obj){
//do your logging
Method closeMethod = obj.getClass().getMethod("close", null);
if (closeMethod != null) {
//log that the method has a .close() method, but does NOT implement Closeable
}
}
This will ensure that first your logging will attempt to close a Closeable object. If that fails, it will fall back to the general Object implementation. And I have added reflection here only to do additional logging, it is not neccessary to use reflection at all in here and I think that you should not be calling close() manually on an object that does not implement Closeable.
For method overloading precedence refer to: http://docs.oracle.com/javase/specs/jls/se7/html/jls-15.html#jls-15.12.2
The answer should work as any object is more specific as Object, as long as it adds something to the functionality.

Related

Using try-with-resources in multiple methods with same AutoCloseable Object

I am trying to modularize my code but it involves passing around my object that implements AutoCloseable. Let say I have two public methods foo1 and foo2:
public class MyClass {
public void foo1() {
// Connection implements AutoCloseable
try (Connection conn = createConnection()) {
foo2(conn);
// is the connection closed or the behavior unpredictable?
conn.doSomethingElse();
}
}
public void foo2(Connection conn) {
try (conn) {
// do something with the Connection
}
}
}
I want to call foo2 from foo1, but also allow other classes to use foo2 separately.
public class OtherClass {
public void doSomething() {
MyClass myClass = new MyClass();
myClass.foo2(createConnection());
}
}
Does this lead to the connection being closed in foo1() after the call to foo2? Or should I put the try-with-resources in the calling methods (such as the doSomething() in OtherClass)?
Your foo1 method closes the connection after foo2 has used it. There is no need for foo2 to close the connection and it shouldn't. You're making it have an unexpected side-effect. E.g. when you call conn.doSomethingElse() inside foo1, you will find it won't work because the connection has been closed by the call to foo2. It's a violation of the principle of least astonishment because the method name does not reveal this side-effect.
If you called it foo2AndCloseTheConnection then you make clear what it does, but I recommend following the rule of thumb that the method that creates the closeable should be the only one to close it. If you follow this consistently, you'll never need to look inside a function to see whether or not something you've opened is closed by that function. You'll simply close it yourself explicitly.
If you want foo2 to be called from other methods, you need to make those methods close the connection:
public void doSomething() {
MyClass myClass = new MyClass();
try (Connection connection = createConnection()) {
myClass.foo2(connection);
}
}
Yes, foo2 closes the connection so it will be invalid when control returns to foo1. Nothing unpredictable about it.
It's a good rule to have things closed by the same code that creates them. But it would be good to be able to nest these things and let them share the same connection and transaction. One solution would be to have each of these data accessing methods receive the connection as a parameter and have an outer layer that gets the connection and makes sure it gets closed.
You're basically trying to reinvent Spring a bit at a time. Spring gives you the ability to have services that can use the same connection and lets you control how and whether transactions are propagated between them. This is done using AOP to wrap objects with around advice that gets the current connection for the thread from a threadlocal data structure. Much easier to use spring (or whatever container).

mock methods in same class

I am using Mockito to mock a method in the same class for which I am writing test. I have seen other answers on SO (Mocking method in the same class), but probably I am misunderstanding them, since I running into issues.
class Temp() {
public boolean methodA(String param) {
try {
if(methodB(param))
return true;
return false;
} catch (Exception e) {
e.printStackTrace();
}
}
}
My Test method:
#Test
public void testMethodA() {
Temp temp = new Temp();
Temp spyTemp = Mockito.spy(temp);
Mockito.doReturn(true).when(spyTemp).methodB(Mockito.any());
boolean status = temp.methodA("XYZ");
Assert.assertEquals(true, status);
}
I however get the expection printed out because definition of methodB gets executed.
My understanding is definition of methodB would get mocked by using spyTemp. However that does not appear to be the case.
Can someone please explain where I am going wrong?
The first issue is that you have to use spyTemp object to expect something from Mockito. Here it is not the same as test. spyTemp is wrapped by the Mockito object temp.
Another issue is that you stub only methodB(), but you are trying to run methodA(). Yes in your implementation of methodA() you call methodB(), but you call this.methodB(), not spyTemp.methodB().
Here you have to understand that mocking would work only when you call it on the instance of temp. It's wrapped by a Mockito proxy which catches your call, and if you have overriden some method, it will call your new implementation instead of the original one. But since the original method is called, inside it you know nothing about Mockito proxy. So your "overriden" method would be called only when you run spyTemp.methodB()
This should work:
Mockito.doReturn(true).when(spyTemp).methodB(Mockito.any());
boolean status = spyTemp.methodA("XYZ");
You created a spy and mocked methodB(). That is correct! But you called methodA() on the original object. To get the correct result call it on the spy
boolean status = spyTemp.methodA("XYZ");
Note the following from Mockito documentation:
Mockito does not delegate calls to the passed real instance, instead
it actually creates a copy of it. So if you keep the real instance and
interact with it, don't expect the spied to be aware of those
interaction and their effect on real instance state. The corollary is
that when an unstubbed method is called on the spy but not on the
real instance, you won't see any effects on the real instance.
This is referring specifically to your situation. You keep a reference to temp and then call its methodA. Mockito is not spying on that instance at all; it's spying on spyTemp. So the normal methodB is called.
Note that you should avoid partial mocks altogether for new code.

Java 7 - custom method decoration without default delegating all, other, many methods

I'd like to decorate the interface PreparedStatement, in order to custom close it (just an example).
This means that I want to decorate an existing instance of PreparedStatement, thus, invoking other code, when close() is being invoked.
For that, I need to default implement all tens of methods of PreparedStatement decorator just to delegate the calls to the inner object, like done here. The downfall is that it's just a lot of work and code with little added value.
Another option is to try and use Java's Proxy and InvocationHandler in order to provide a default implementation that does the delegate for all the methods in a single method. If a custom method exists, the InvocationHandler, directs the call to it. See example here.
The problem with this solution is that the custom method cannot be marked as #Override and its signature cannot be checked for correctness, as it will require an abstract PreparedStatement, which the Proxy will not be able to instantiate.
So, can this be done? How?
* Must be able to implement using Java 7 max, but feel free to provide Java 8 answers.
As far as I understood you want to provide to the interface PreparedStatement concrete implementation. The only way I can think of is by creating abstract class that implements the interface. By doing so you don't need to implement all the methods from the interface and you'll have your desired implementation.
I'd try something like this:
public abstract class MyPreparedStatement implements PreparedStatement {
#Override
public void close() throws SQLException {
System.out.println("Closing");
}
public static void main(String[] args) throws SQLException {
Connection con = null;
MyPreparedStatement statement = (MyPreparedStatement) con.prepareStatement("sql");
}
}
Can you explain in clearer terms what the Proxy solution is lacking? Consider something like this, which relies on a AOP-esque 'hook':
final PreparedStatement original = ...;
final InvocationHandler delegator = new InvocationHandler() {
void onClose() {
/* do stuff */
}
Object invoke(final Object proxy, final Method method, final Object[] args) {
if (method.getName().equals("close")) {
onClose();
}
return method.invoke(original, args);
}
};
final PreparedStatement wrapped = (PreparedStatement) Proxy.newProxyInstance(this.getClass().getClassLoader(),
new Class<?>[] { PreparedStatement.class }, delegator);
If you don't have access to the methods in order to do the usual inheritance thing with them, you can accomplish what you are attempting to do with Aspect Oriented Programming, leveraging AspectJ or the Spring Framework aspect functionality to provide advice on your desired methods.
A simple aspect basically comes down to:
#Aspect
public class MyAspect {
#Pointcut("execution(* *(..))") //Replace expression with target method; this example
//will hit literally every method ever.
public void targetmethod() {}; //Intentionally blank.
//AspectJ uses byte code manipulation (or "black magic voodoo", if you
// will) to make this method a surrogate for any real one that matches the pointcut
#Before("targetmethod()") //Or #After, or #Around, etc...
public void doStuff() throws Throwable {
//Put your code here
}
}
Once you have your aspects together, add them to your aop.xml and weave your aspects (you can do this at compile time with appropriate build manager configuration, or at run time by running aspectjweaver with java -javaagent:/path/to/aspectjweaver.jar).
This does come with a disclaimer however: doing things like this to java.* classes allows you break things in new and interesting ways with all the side-effects you're introducing (in fact, AspectJWeaver refuses to weave into java.* classes by default, though you can override that setting). Be very aware of what you are doing, and use your aspects and aspected methods wisely.

How to automate Hibernate boilerplate in RMI remote methods

I have an RMI class that accepts remote calls from clients.
This class uses Hibernate to load entities and perform some business logic, in general read-only.
Currently most of the remote methods bodies look like that :
try {
HibernateUtil.currentSession().beginTransaction();
//load entities, do some business logic...
} catch (HibernateException e) {
logger.error("Hibernate problem...", e);
throw e;
} catch (other exceptions...) {
logger.error("other problem happened...", e);
throw e;
} finally {
HibernateUtil.currentSession().getTransaction().rollback(); //this because it's read-only, we make sure we don't commit anything
HibernateUtil.currentSession().close();
}
I would like to know if there is some pattern that I could (relatively easily) implement in order to automatically have this "try to open session/catch hibernate exception/finally close hibernate resources" behavior without having to code it in every method.
Something similar to "open session in view" that is used in webapps, but that could be applied to remotr RMI method calls instead of HTTP requests.
Ideally I would like to be able to still call the methods directly, not to use some reflexion passing method names as strings.
I would suggest you to use spring+hibernate stack. This saves us a lot of repeatable code which I guess you are looking for. Please check this link. Its actually an example of web application but same can be use for a standalone application as well.
All i wanted was a "quick and clean" solution, if possible, so no new framework for now (I might use Spring+Hibernate stack later on though).
So I ended up using a "quick-and-not-so-dirty" solution involving a variant of the "Command" pattern, where the hibernate calls are encapsulated inside anonymous inner classes implementing my generic Command interface, and the command executer wraps the call with the Hibernate session and exception handling. The generic bit is in order to have different return value types for the execute method.
I am not 100% satisfied with this solution since it still implies some boilerplate code wrapped around my business logic (I am especially unhappy about the explicit casting needed for the return value) and it makes it slightly more complicated to understand and debug.
However the gain in repetitive code is still significant (from about 10 lines to 3-4 lines per method), and more importantly the Hibernate handling logic is concentrated in one class, so it can be changed easily there if needed and it's less error-prone.
Here is some of the code :
The Command interface :
public interface HibernateCommand<T> {
public T execute(Object... args) throws Exception;
}
The Executer :
public class HibernateCommandExecuter {
private static final Logger logger = Logger.getLogger(HibernateCommandExecuter.class);
public static Object executeCommand(HibernateCommand<?> command, boolean commit, Object... args) throws RemoteException{
try {
HibernateUtil.currentSession().beginTransaction();
return command.execute(args);
} catch (HibernateException e) {
logger.error("Hibernate problem : ", e);
throw new RemoteException(e.getMessage());
}catch(Exception e){
throw new RemoteException(e.getMessage(), e);
}
finally {
try{
if(commit){
HibernateUtil.currentSession().getTransaction().commit();
}else{
HibernateUtil.currentSession().getTransaction().rollback();
}
HibernateUtil.currentSession().close();
}catch(HibernateException e){
logger.error("Error while trying to clean up Hibernate context :", e);
}
}
}
}
Sample use in a remotely called method (but it could be used locally also) :
#Override
public AbstractTicketingClientDTO doSomethingRemotely(final Client client) throws RemoteException {
return (MyDTO) HibernateCommandExecuter.executeCommand(new HibernateCommand<MyDTO>() {
public AbstractTicketingClientDTO execute(Object...args) throws Exception{
MyDTO dto = someService.someBusinessmethod(client);
return dto;
}
},false);
}
Note how the client argument is declared final, so it can be referrenced inside the inner class. If not possible to declare final, it could be passed as parameter to the executeCommand method.

pattern to proxy (different) methods to many different classes

I have a bunch of classes with a unique set of methods.
class1 {
method1(dbconn, args...);
method2(dbconn, args...);
}
class2 {
method3(dbconn, args...);
method4(dbconn, args...);
}
class3 {
method5(dbconn, args...);
}
We need to expose all the methods via a flat library:
class library {
init () {
//create instance of all helper classes
}
method1(args...) {
return class1Instance.method1(getDbconn(), args...);
}
method2(args...) {
return class1Instance.method2(getDbconn(), args...);
}
method3(args...) {
return class2Instance.method3(getDbconn(), args...);
}
method4(args...) {
return class2Instance.method4(getDbconn(), args...);
}
method5(args...) {
return class3Instance.method5(getDbconn(), args...);
}
}
But it is very time consuming, and there is a lot of repetitive code to move each method into the library. Is there a better way to do this?
Note that each method name is unique. The arguments and return value are of different types.
define an interface:
interface library {
method1();
...
methodN();
}
then use dynamic proxy to reflectively invoke methods of your service implementations. you will also have to find a solution on how to choose on which service particular method should be invoked. but this is not very hard.
you can implement a class:
class ServiceDemultiplexer implements InvocationHandler {
ServiceDemultiplexer(Object services[]) {
...
}
public Object invoke(Object proxy, Method m, Object[] args)
throws Throwable
{
...
}
}
The better way of doing it it to avoid doing it.
A class should have a well-defined, as coherent as possible, set of responsibilities. If all these classes exist, it's certainly because each one has a different set of responsibilities than the other ones. Why don't you let the caller choose the appropriate class to use and call the appropriate method from this class.
You could use your Library class as a factory of helper classes. The callers would just have to do
library.getClass1().method1(...);
If you guive it real names, it becomes more natural:
library.getProductManager().createProduct();
But even then, injecting the specific dependencies to caller object looks better to me than relying on a huge factory like this. Use a dependency injection framework like Spring or Guice.
Depending on what you are working on and if using reflection is not an issue, you might call everything through a dynamic proxy.
http://www.javaworld.com/javaworld/jw-11-2000/jw-1110-proxy.html
Your InvocationHandler.invoke would just locate class and method declaring Method m in its parameter, instantiate an object of that class (could be done sooner than that too) and pass the call to it. The actual implementation depends on what you already have.

Categories