Any way to remove logging calls without using ProGuard optimization? - java

I have a wrapper class for making log calls during development. This makes it easy to turn all logging on or off at any given time (plus some other nifty features). Previously I used a specific ProGuard optimization to remove this class during release, which also removed the calls to the class's static methods (so no log strings were left behind).
Unfortunately because of this, I have to disable ProGuard's optimization feature. While I can easily turn off the logging, all of my log strings are still visible in the resulting apk, and unless I'm missing something, there is no other way in ProGuard to remove them.
Is there any other way to remove these strings when building a release package in the Eclipse GUI? (not ANT)

I don't know where you string literals are etc. but to simulate a ifdef debug statement you would do something similar to this which may be trivial if you can just wrap all the affected inner class/method/var's of your debugging class in such a statement.
Apparently the compiler removes anything it finds in that block as more or less dead code, or so I have read, never checked it out though.

Related

Is it ok to have unused Components in project?

Generally unused/dead code is bad but I wonder what to do with unused components.
Imagine that I have application that sends notifications to users, it sends EmailNotification but after some time we switch to sending notifications with SMS. Instead of deleting EmailNotification class i create interface let's say Notification and I have such structure:
Notification
--SmsNotification
--EmailNotification
I don't want to remove EmailNotification, because after some time we can go back to EmailNotifications and this change will be as easy as mark EmailNotification class as #Primary.
In such case one of the implementations is always dead code and I wonder if it is ok or generally how to deal with that?
Actually this is not the best practice.
Instead of this practice, you can separate your code into two different modules, one per component. By this way you can utilize any of two modules depending on your needs through your build automation tool (maven or gradle for example). So the produced jars will contain no dead code.
I would agree that this is not dead code, just unused code. However the code in production should be as clean as possible and so if using version control such as git, I would remove the code as it will always be there in the history of the git repository. If you do not want to do this, then I would suggest a way of explaining why the code is there, some thing like a java doc or readme file.
There should not be any problem in keeping the old code, which might become reusable in future. As a matter of fact, the design itself should be so that it can accommodate changes in components without severe impacts.
But if there is an unreachable block of code, which certainly will not add any value to the product in present or future, it will be better removed, because it will unnecessarily increase the number of lines of code and will slow down the process of testing, ultimately impacting the delivery. Additionally, this unused code block will also appear in the final product (the JAR/WAR) unwantedly increasing its size.
In my case, I was using SonarQube for static code analysis and there were blocks of code, methods and sometimes files which will show up only at the time of testing. It was slowing down the process as well as taking otherwise unnecessary heap space. Getting rid of those blocks certainly helped us speed up the process.
One thing you should be aware of is that even unused components need to be maintained. Some examples that come to my mind:
If the Notification interface changes, EmailNotification has to be changed too
If you update dependencies used by multiple components, you by might need change EmailNotification too
If you change or introduce new quality measures (e.g. x% of code coverage, specific code styles, no warnings policy etc.), they also apply to unused components - which leads to additional work
The changes required to maintain unused components could be obvious (because it does not compile any more) or subtly (they still compile but since they are not used, no one notices that they fail at runtime). Even if compile errors get fixed, chances are that they are not getting tested properly.
So by keeping unused modules you might have to do more work than necessary for certain changes and you still run the risk of having a broken module that you can't just turn on when needed. It could easier to just retire the component and revive and update it when it is actually needed. You could wait with the retirement until there actually is a breaking change though. If you are lucky, no breaking change comes before the component is needed again.
If you are certain that you'll need the component again in near future, then keep it. But make sure to maintain it properly.

"Object Breakpoint" - How to debug acess to a specific Object in a large code base with complex dynamic behavior?

Every once in a while I'm in the Eclipse Debug mode, and wish I could simply pick the Object that I am currently inspecting/watching, put some kind of "Object Breakpoint" on it, and step to the next line of code that accesses it.
Now, I know that I can put breakpoints on Classes, but I usually have hundreds or even thousands of instances in memory, most of which have a long life time. They often go in and out of frameworks. They are wrapped into Collections, filtered and unwrapped again. In short: a regular, large application.
Usually I still find the problem by looking for rare features of that Object, using conditional method breakpoints and a lot of informed guessing. However, I think I sometimes could be much faster if I had something like the described feature.
What I found after some searching is the Debug Proxy (scroll down to examples). It is a container class that will use Javas reflection API to make itself look like the contained Object, thus you can use it instead of the contained Object in your application. Being an InvocationHandler, the DebugProxy can now "intercept" invocations of methods in the contained Object.
Using the proxy for actual debugging is as easy as adding this line to your application.
IMyObject = (IMyObject) DebugProxy.newInstance(new MyObject());
I can then set breakpoints inside the DebugProxies source code.
However, there are at least two problems with this approach.
It works but it is still a hack, and there are a lot of features missing, such as filtering options.
The Proxy-Object cannot be down-cast to the implementing class.
The 2. problem is the more serious one. I was able to use the DebugProxy with Classes generated by EMF, and there is no problem to follow the Object throughout the Framework. However, when I am trying to debug code that doesn't use interfaces for all interesting Classes, the DebugProxy will quickly fail.
Does anybody know about alternatives?
Maybe the Eclipse JDT Debugger already has such a feature and I simply don't see it!?
I know there is the Java instrumentation API, and frameworks such as AspectJ. Could these be used to get a practical solution?
I added basic filtering to the DebugProxy and modified the output so Eclipse Console View shows a link to the calling line of code:
Problem number two remains unsolved, though. I put up the source code on GitHub. Maybe somebody will come up with something.
A completely different way to approach this would be to automatically add breakpoints with conditions comparing the current hashCode() with the HashCode of the Object in question. This may not be too difficult for someone who knows more about the JDT internals.

Is there any class to diagnose invoked method in a java class?

I need to diagnose all invoked methods in a class(either declared in the class or not) using it's source code. Means that give the class source code to a method as an input and get the invoked method by the class as the output. In fact I need a class/method which operates same as java lexical analyzer .
Is there any method to diagnose all invoked methods ?
of course I tried to use Runtime.traceMethodCalls(); to solve the problem but there was no output. I've read I need to run java debug with java -g but unfortunately when I try to run java -g it makes error. Now what should I do ? Is there any approach ?
1) In the general case, no. Reflection will always allow the code to make method calls that you won't be able to analyze without actually running the code.
2) Tracing the method calls won't give you the full picture either, since a method is not in any way guaranteed (or even likely) to make all the calls it can every time you call it.
Your best bet is some kind of "best effort" code analysis. You may want to try enlisting the compiler's help with that. For example, compile the code and analyze the generated class file for all emitted external symbols. It won't guarantee catching every call (see #1), but it will get you close in most cases.
You can utilize one of the open source static analyzers for Java as a starting point. Checkstyle allows you to build your own modules. Soot has a pretty flexible API and a good example of call analysis. FindBugs might also allow you too write a custom module. AFAIK all three are embeddable in the form of a JAR, so you can incorporate whatever you come up with into your own custom program.
From your question it is hard to determine what is exactly problem you're trying to solve.
But in case:
If you want to analyze source code, to see which parts of it are redundant and may be removed, then you could use some IDE (Eclipse, IntelliJ IDEA Community Edition etc.) In IDE's you have features to search for usages of method and also you have functionality to analyze code and highlight unused methods as warnings/errors.
If you want to see where during runtime some method is called, then you could use profiling tool to collect information on those method invocations. Depending on tool you could see also from where those methods were called. But bare in mind, that when you execute program, then it is not guaranteed that your interesting method is called from every possible place.
if you are developing an automated tool for displaying calling graphs of methods. Then you need to parse source and start working with code entities. One way would be to implement your own compiler and go on from there. But easier way would be to reuse opensourced parser/compiler/analyzer and build your tool around it.
I've used IntelliJ IDEA CE that has such functionalitys and may be downloaded with source http://www.jetbrains.org/display/IJOS/Home
Also there is well known product Eclipse that has its sources available.
Both of these products have enormous code base, so isolating interesting part would be difficult. But it would still be easier than writing your own java compiler and werifying that it works for every corner case.
For analyzing the bytecode as mentioned above you could take a look at JBoss Bytecode. It is more for testing but may also be helpful for analyzing code.
sven.malvik.de
You may plug into the compiler.
Have a look the source of Project Lombok for instance.
There is no general mechanism, so they have one mechanism for javac and one for eclipse's compiler.
http://projectlombok.org/

java runtime tracing library to replace system.out.println

Have you heard of any library which would allow me to set up tracing for specific methods at runtime?
Instead of adding (and removing) lots of System.out.println in my code (and having to re-compile and re-deploy) I would like to have a magic thing which would print out a line for each call of selected method without any change in the code. This would work without re-compiling, so some kind of JVM agent (or some non-standard JVM would be needed?). Sounds like a job for aspect programming?
A typical scenario would be to start an application, configure the traced methods dynamically (in a separate file or similar) and then everytime a selected method is called a line with its name (and arguments) is printed out to System.out (or some log file).
Naturally one could think of tens of additional features, but this basic set would be a great tool. BTW, I use Eclipse interactive debugger too, not only the System.out tracing technique, but both have some advantages and sometimes Eclipse is not enough.
Yes what you are referring to is known as Aspect oriented programming. A typical library providing this for Java is AspectJ. You define what are called pointcuts, essentially regular expressions for classes and method names, including wildcards, and the code to execute at each pointcut, known as an advice. This is useful for logging and also security checks and similar cross cutting concerns.
You can turn pointcut advices on and off through configuration. You can have an advice execute before a method call, after it returns or even after it throws an exception. Arguments are also available.
An aspectj java agent is needed for this to work.
In my experience, that kind of very detailed tracing (much more detailed than one would normally use for logging) as a debugging technique is indicative of insufficient unit testing and integration testing.
You can do this using a tool called InTrace.
NOTE: InTrace is a free and open source tool which I have written.
Log4J useful for disabling logging depending on "log-level" (DEBUG, INFO, WARN, FATAL).
You specify in configuration file what the least level you want to appear in logs, e.g., don't log anything below INFO level, and voila!
Looks like there's yet another solution - called Byteman. In their own words:
Byteman is a tool which simplifies tracing and testing of Java
programs. Byteman allows you to insert extra Java code into your
application, either as it is loaded during JVM startup or even after
it has already started running. The injected code is allowed to access
any of your data and call any application methods, including where
they are private. You can inject code almost anywhere you want and
there is no need to prepare the original source code in advance nor do
you have to recompile, repackage or redeploy your application. In fact
you can remove injected code and reinstall different code while the
application continues to execute.
Jackplay is the tool you are looking for.
It allows you to enable logging on method entry and exit points without any coding or redeployment.
It also allows redefining a method body. It gives you web based UI as control panel to enable or undo tracing on your class.methods.

How to disable AspectJ without restarting the program?

I have an application using AspectJ with load time weaving to advise various methods. I would like to put a switch in my program to disable the aspect without having to make any source code changes or having to restart the program. It needs to incur as little overhead as possible while turned off. Thanks!
To my knowledge, there is no way to unweave some advice from bytecode. If you're working with an existing piece of augmented bytecode, I don't believe there's any way to remove it other than restarting the application without the weaving*.
If you're talking about setting things up so they can be removed - it may be true that the weaving can't be removed, but you could certainly add a global if (useWeavedCode) check around all of it, and of course add that variable as well as methods to modify it in an appropriate way (expose via JMX, new console command, new admin JSP page, etc.). Then if you want to prevent this new behaviour, you can disable it with this new option.
Note of course that this doesn't actually remove the code, and incurs the cost of a boolean
parameter lookup while it's disabled, but I don't think it's possible to do better than that.
*Strictly you need to get the class loaded again, so you don't need to restart the app, but in practice this is likely the most straightforward option available to you unless you've previously put hooks into the classloaders.

Categories

Resources