views:

250

answers:

4

I am looking for a way to remove all uses of a particular class, including the class itself, at compile time. Basically a form of pre-processing, but I'd like to do it without having to surround all the instances with #ifdebug ... #endif.

Is there any ant-based tool out there that can do this? If not, can anyone point me in the right direction for how to write such a tool? (not a minor undertaking I know, but if its the only option...)

The situation is I have a helper class for debugging function calls. This is instantiated at the beginning of a function and a call is made at the end. This is a JavaME application so I'm nervous about the overhead this is adding to performance. I already have a release and debug build that have pre-processor directives using ProGuard, so I would like to exclude the use of this helper class from the release build. It doesn't appear this can be done with ProGuard.

+1  A: 

Do you know that this debug code will make the JavaME app slow? You could also try creating a way to conditionally call these debug methods.

A few more ideas ... I've never written a JavaME app, but I assume there is way to run/test with running on the actual device. Given this way of running/testing, perhaps you can use Eclipse/Netbeans to debug your code and use proper breakpoints instead of programmatically tracing method calls. No harm to compiled code in this case. Also consider using AspectJ to trace method calls, this can be conditionally done after code is compiled since AspectJ alters bytecode directly (not sure how this plays with JavaME). Lastly, I've heard of people using the standard GNU C/C++ preprocessor on Java. I have no idea if it works, google will help you.

basszero
+3  A: 

"This is instantiated at the beginning of a function and a call is made at the end. "

If this is all over your code maybe you need to look at AOP.

or a state design pattern for the helper class, in test mode it does one thing but in prod it does another(like nothing)

l_39217_l
Can you use AOP with JavaME? A quick google didn't reveal anything conclusive...
Outlaw Programmer
look for AspectJhttp://www.eclipse.org/aspectj/doc/released/faq.php#q:requirements
l_39217_l
A: 

Not exactly what you want but...
You could separate your code to modules (core and debug, in your case), then make sure modules call each other via reflection: use an interface available in core, create a wrapper class in core that will hide object instantiation via reflection detail/ Then, on production, just omit the debug code and have the wrapper "do nothing" if the instantiation fail / when you set a specific flag.

This way your debug classes won't make it into production and you won't have to "statically link" to them so your core production code won't care. Of course, this is only possible if your debug code has no side effects visible to core code, but it seems that's your case (from your problem description).

Ran Biron
A: 

Is it possible to just create the class once, on application startup, instead of creating an instance for each method? Your debug class could then look like this:

public class Debug // maybe make this a *gasp* singleton?
{
    public static void start(); // called at start of method
    public static void end();   // called at end, probably should be in a finally block

    public static void setDebugMode(boolean debugOn); // turn off for production mode
}

Set debug mode to "true" in testing but "false" in production. When debug mode is off, none of the methods do anything (except check the state of debug mode, of course).

You don't avoid the overhead of the function call, and you do need to check the state of that boolean, but you do get to avoid jumping through hoops trying to avoid load the class at all.

This will need more work if you have a multithreaded application, too.

Outlaw Programmer
If you make debugOn static and final, and skip the setDebugMode() method, the compiler might well be able to optimize the function calls away. Even if it can't, it should be able to optimize away the method bodies of start() and end().
Michael Myers
True, but I was also thinking that the setDebugMode would be read from a properties file or something. At my job, each layer (staging, prelive, live) has its own properties file. In this case, a DEBUG_MODE property would be ON for staging but OFF in live. Maybe the OPs environment is similar...
Outlaw Programmer