I have created a java class which delegates all calls to another class.
I want that on each method call program will output some info - method name and arguments.
There are very many methods in that class, so I don't want to insert System.out.println() in each method manually.
Is there any way to do it with regex?
here is a sample method with required println() line:
private final PreparedStatement statement;
#Override
public void setNull(int parameterIndex, int sqlType) throws SQLException {
System.out.println("setNull: parameterIndex=" + ", sqlType" + sqlType);
statement.setNull(parameterIndex, sqlType);
}
For this cases and similar we do not updated every function to add println, we usually use something that called AOP (Aspect Oriented Programming).
AOP is a useful technique that enables adding executable blocks to the source code without explicitly changing it. In our example, we don't want to log method execution inside the class. Instead, we want some other class to intercept every call to method power(), measure its execution time and send this information to slf4j.
please read this for more details aop-aspectj-java-method-logging and
logging-with-aop-in-spring
AOP give you ability to intercept method execution and add your logic before,after or around the execution, so in your case you can add before execution interceptor and print the msg that you want.
AOP example :
#Aspect
public class MyLogger {
private Logger log = Logger.getLogger(getClass());
#before("execution(* *(..))") // after execution of any function
public void log(JoinPoint point) {
System.out.println(point.getSignature().getName() + " called...");
}
}
You can also use point.getArgs() to get all method arags
Related
I am trying to add some convenient methods to java.util.Logger. They are methods that I expect to ease the coding o my next Java application:
public void severeException(Exception e, String msg) {
super.severe(msg);
super.severe(e.getClass().getCanonicalName());
super.severe(e.getMessage());
}
public void severeLoadingFile(Exception e, String filePath) {
super.severe("Could not load file '" + filePath + "'");
super.severe(e.getClass().getCanonicalName());
super.severe(e.getMessage());
}
public void severeLoadingFile(String filePath) {
super.severe("Could not load file '" + filePath + "'");
}
They represent a 1:2 to 1:3 ratio in the number of code lines I have to write whenever I want to report an exception. There are a large bunch of similar methods for well-known exceptions, like IOException loading a file, etc.
So far I have tried extending Logger as CustomLogger, which led me to problems with class loaders and modules when calling getLogger() method. Then I tried initializing CustomLogger by its constructor...
Beyond the problems with constructor and class loaders, this does not seem to be the way, as the caller method gets trapped by my wrapping methods.
I have scanned the Logger source code but did not find an easy way of calling log() passing it the caller's name or something similar.
Any idea?
It is not impossible yet may impact performance.
In your logging method you can find the caller's name via the stack trace element (https://docs.oracle.com/javase/8/docs/api/java/lang/StackTraceElement.html).
System.out.println(Thread.currentThread().getStackTrace()[1]);
I second Anders's idea of making proper use of a logging framework.
How would I mock methods that accept a lambda using Mockito so that I am able to control which arguments are passed into the callback? I am specifically trying to mock the JDBI method useExtension which is used like this:
jdbi.useExtension(OrgUnitDao.class, dao -> {
// Skip if already loaded
// Skip if already loaded
if (dao.orgUnitsAreLoaded()) {
I would like to substitute the dao object passed back into the callback so that I could control the branching using the return value of dao.orgUnitsAreLoaded().
The signature looks like this
public <E,X extends Exception> void useExtension(Class<E> extensionType,
ExtensionConsumer<E,X> callback)
throws NoSuchExtensionException,
X extends Exception
This is the full answer to my question. It's simplified down to the very basics of how to do the stubbing and so doesn't reflect the production code I am to test, but it shows exactly the mechanics needed to do it.
final Jdbi jdbi = mock(Jdbi.class);
doAnswer(invocation -> {
System.out.println("this is the doAnswer lambda - just setting up the answer and the mocks");
final Class<OrgUnitDao> daoClass = invocation.getArgument(0);
final ExtensionConsumer callback = invocation.getArgument(1);
final OrgUnitDao mock1 = mock(daoClass);
when(mock1.orgUnitsAreLoaded()).thenReturn(false);
// call the actual callback method
callback.useExtension(mock1);
return null;
}).when(jdbi).useExtension(eq(OrgUnitDao.class), any());
// This is the method call I am to test
// Regard this as hidden away in some outer method in
// the System-Under-Test, but that I have been able
// to inject all its dependencies
jdbi.useExtension(OrgUnitDao.class, new Foo());
/// Further down, outside of the method
// Only replaced the lambda with this to get toString() for debugging ...
class Foo implements ExtensionConsumer<OrgUnitDao, RuntimeException> {
#Override
public void useExtension(OrgUnitDao orgUnitDao) throws RuntimeException {
System.out.println("A real method call, now using the passed in mocked dao:" + orgUnitDao.orgUnitsAreLoaded());
}
#Override
public String toString() {
return "OrgUnitDao class";
}
}
To parallel the conversation on the question "Calling callbacks with Mockito", your lambda might be called synchronously during the execution of your method-under-test, or it might be called later based on some external factor or interaction. Like Dawood's answer there, your answer here using a Mockito Answer will work, and is the only way to go if you are looking for the synchronous style (where mockJdbi calls your lambda immediately before methodUnderTest returns). If your lambdas are going to be called asynchronously, or if your system tolerates you calling the lambda asynchronously, you might want to test the state after your method-under-test returns but before you interact with the lambda.
// MockitoJUnitRunner, MockitoRule, or MockitoAnnotations.initMocks populate these.
// Especially useful for the ArgumentCaptor's generic arguments.
#Mock Jdbi mockJdbi;
#Mock OrgUnitDao mockOrgUnitDao;
#Captor ArgumentCaptor<ExtensionConsumer<OrgUnitDao, RuntimeException>>
extensionConsumerCaptor;
#Test public void yourTest() throws Exception {
// No stubbing needed! Just create the system under test.
YourSystemUnderTest systemUnderTest = new YourSystemUnderTest(mockJdbi);
// Call the method under test, which presumably calls useExtension(...).
systemUnderTest.methodUnderTest();
// Assert anything that should be true before the lambda is called.
assertFalse(systemUnderTest.getSomeState());
// Confirm that useExtension was called, and simultaneously acquire the lambda.
// ArgumentCaptor.capture() is a matcher, so every argument requires a matcher like eq.
verify(mockJdbi).useExtension(eq(OrgUnitDao.class), extensionConsumerCaptor.capture());
// Prepare the mock DAO and call the lambda.
when(mockDao.getFoo()).thenReturn("bar");
extensionConsumerCaptor.getValue().useExtension(mockDao);
// Assert anything that should be true after the lambda is called.
assertTrue(systemUnderTest.getSomeState());
}
Though lambdas reduce the boilerplate previously associated with anonymous inner classes, you may also prefer using the Captor style because it saves you from creating lengthy Answer implementations and hiding your test assertions or Mockito verifications in them. This is especially tempting if your project prefers BDD-style mocks with clear "given-when-then" structure (though my example more-closely resembles "given-when-then-when-then").
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.
In Java, it is possible to get the class and method that called the current method (the method in which you get the StackTrace).
Can I get the arguments that were passed to the method that called this method?
I need this for debugging purposes.
Eg:
baseClass {
initialFunc(input) {
var modifiedInput = input + " I modified you";
otherClass.doSomething(modifiedInput);
}
}
otherClass {
doSomething(input) {
//GET THE ARGUMENTS PASSED TO THE METHOD OF THE CLASS THAT CALLED THIS METHOD
}
}
Can one get this information from the stacktrace, or are there other means?
(Note that I need to be able to do this in runtime and cannot actually change the source of baseClass, this is going to be a feature of my debugging class that does not know the source beforehand)
I don't believe this is possible using the standard Java API.
What you could do is to use AspectJ, place a point-cut at the calling method, save the arguments, place a point-cut at the called method and pass on the arguments.
Another option (slightly more advanced) is to use a custom, bytecode-rewriting, class loader that saves the original arguments, and passes them on as extra arguments to the next method. This would probably take a day or two to implement. Suitable frameworks are BCEL or ASM.
I think this could be possible, because input is out of scope but isn't yet accessible for garbage collection, so the value still exists, but unfortunately I don't believe there is an default API way to access it. This could be maybe possible with a custom implemented NDC (nested diagnostic context) for the logging approach.
I'm not sure why you'd ever want to do this in Java?
The only way I can think of is to create a custom wrapper object for the passed string, thus sending the reference to the wrapper instead of a new string each time.
I'd advice against it, though, since it clutters your original code, and makes it even more error prone.
Might this problem not be solved using a debugger, like the one built into eclipse, to inspect your state?
In my case, I needed to get a parameter value has been passed to a method in a certain stack frame to be used later within the execution flow
I used ThreadLocal to store it and when I needed it I was able to retrieve it at any point in code as I declared it as public static
here is a skeleton example
public static final ThreadLocal<SomeType> IMPORTANT_THREAD_LOCAL_FOR_BLA = ThreadLocal.withInitial(whatever);
methodWithImportantParam(SomeType importantValue){
// save it in the static threadLocal Field
this.IMPORTANT_THREAD_LOCAL_FOR_BLA.get()=importantValue;// code to set the value
// continue method logic
}
and somewhere in code where you need that value
YourClass.IMPORTANT_THREAD_LOCAL_FOR_BLA.get()
but make sure the execution flow that you set the value then you retrieve it
hope my answer add something valuable to this question
You can get name of caller method and its class, but you have to add some code in current method:
public static void main(String[] args) throws Exception {
call();
}
private static void call() {
Exception exception = new Exception();
for(StackTraceElement trace : exception.getStackTrace()){
System.out.println(trace.getMethodName());
}
}
This will print "call" and "main", methods name in called order (reverse).
This is possible using Reflection API !
public class StackTrace {
public static void main(String args[]) {
StackTrace st = new StackTrace();
st.func();
}
public void func() {
OtherClass os =new OtherClass();
os.getStackTrace(this);
}
}
class OtherClass {
void getStackTrace(Object obj) {
System.out.println(obj.getClass());
}
}
Most of the methods in my application are written like this:
public void m() {
long t1 = System.currentTimeMillis();
log.info("begin - m()");
/* method body */
long t2 = System.currentTimeMillis();
log.info("end - m(), took " + (t2 - t1) + "ms.");
}
I wish I could simply annotate my method and have the log statements be automagically generated instead:
#Log("executionTime")
public void m() {
/* method body */
}
Any ideas on how to proceed with this approach ? Is there any known solution ?
Someone suggested AOP for this. The problem is that with AspectJ or Spring AOP I would have to describe all the methods which ammounts to as much code as the log calls in the method itself.
AspectJ and Spring AOP support something like:
execution(* com.company.project..*.*(..))
which will cover all methods in all sub-packages of project. So no need to define all methods one by one.
As has been suggested to you, AOP fits well to serve this requirement. Not sure what you meant by "having to describe all methods". From what I know there are ways to use wildcards to specify methods to which aspects apply, which could ease your work of "describing"..this is true at least in the case of Spring AOP..not sure about others.
And yes, CGLIB suggested by Maurice is another good candidate for your consideration. Never used it though.
CGLIB let you modify method code at runtime
AspectJ has the concept of a join point, which is like a wildcard that can specify any methods that match that wildcard (you can specify particular methods in a class or any class that matches the wildcard). Then you can create an aspect which contains before advice and after advice, which are methods that run before and after the method matched by the join point. You can generate your log methods this way.
Perf4j supports getting timing information for methods using annotations. See here in their developer guide.
While this is not an actual practical answer to your question just yet (some good answers have been with respect to AOP), I believe the concept of ARM in Java 7 should be a viable option for implementing something like this on a small scale.
You could define a utility logging class and a factory to produce that class, something like the following:
public class TimerFactory
{
private static final Logger log = ...; // Obtain however
static class Timer implements Disposable<RuntimeException>
{
private final long startTime;
private final String name;
private Timer(String name)
{
this.name = name;
startTime= System.currentTimeMillis();
log.info("begin - " + name);
}
public void close()
{
final long t2 = System.currentTimeMillis();
log.info("end - " + name + ", took " + (t2 - t1) + "ms.");
}
}
public static Timer getTimer(String name)
{
return new Timer(name);
}
}
Now with that boilerplate out of the way (essentially an encapsulation of your logging behaviour), it could be called as follows:
public void m() {
try (TimerFactory.getTimer("m()")) {
/* method body */
}
}
The first log method would be called at the entrance to the try block, and the start time recorded. When the try block was exited, the resource (the Timer in this case) would automatically be "closed", which would cause the final time to be calculated and logged. Note as well that because this is a try block, the end logging will happen regardless of whether an exception is thrown or not. Your original code should probably use a try-finally block to ensure that the logging is actually completed.
Obviously this still requires you to put some logging code at each site, so is not really a replacement for clever pointcuts and AOP, even once Java 7 is released. However, if you find yourself dropping the logging in every now and then into perhaps a handful of methods, this pattern is a good way to abstract out the logging concerns and allow you to reuse it with the minimum of boilerplate.
You should use an aspect to this requirement. This requirement is a crosscuting concern (a concern that "cuts" between many classes).
To capture the methods that you want match you should create a pointcut that matches one or more join points. A join point is something that can be executed on your code (a method for example).
Look at this simple examples about tracing and logging and at this link about wildcards and pointcuts.
Try #Loggable annotation from jcabi-aspects (powered by AspectJ):
#Loggable(Loggable.DEBUG)
public String load(URL url) {
return url.openConnection().getContent();
}
It logs through SLF4J, which you can redirect to your own logging facility like, say, log4j.
Comment out the logging or profiling calls with a unique search term:
void myfunc() {
//log-call-123: try { long log_t1 = System.currentTimeMillis();
//log-call-123: log.info("begin - myfunc()"); {
...
normal method code
...
//log-call-123: } } finally { long log_t2 = System.currentTimeMillis();
//log-call-123: log.info("end - myfunc(), took " + (log_t2 - log_t1) + "ms."); }
}
When you search and replace:
Search for: "//log-call-123:"
Replace with: "/* log-call-123 */"
Do the reverse search and replace when you want to turn off extra logging or profiling calls.