Question

Sometimes for testing/developing purposes we make some changes in the code that must be removed in a production build. I wonder if there is an easy way of marking such blocks so that production build would fail as long as they are present or at least it will warn you during the build somehow.

Simple "//TODO:" doesn't really work because it is ofter forgotten and mixed with tons of other todos. Is there anything stronger?

Or maybe even if I can create some external txt file and put there instructions on what to do before production, and that ant would check if that file is present then cancel build.

We are using Eclipse/Ant (and java + Spring).

Update: I don't mean that there are big chunks of code that are different in local and production. In fact all code is the same and should be the same. Just lets say I comment out some line of code to save lot of time during development and forget to uncomment it or something along those lines. I just want to be able to flag the project somehow that something needs an attention and that production build would fail or show a warning.

Was it helpful?

Solution

You could also just define stronger task comment markers: FIXME (high priority) and XXX (normal priority) are standard in Eclipse, and you could define more task tags (Eclipse Properties -> Java -> Compiler -> Task Tags)

If you want to fail your build, you could use the Ant (1.7) contains file selector to look for files containing specified text:

<target name="fixmeCheck">
  <fail message="Fixmes found">
    <condition>
      <not>
        <resourcecount count="0">
          <fileset dir="${pom.build.sourceDirectory}"
                   includes="**/*.java">
             <contains text="FIXME" casesensitive="yes"/>
          </fileset>
        </resourcecount>
      </not>
    </condition>
  </fail>
</target>

<target name="compile" depends="fixmeCheck">

Obviously, change ${pom.build.sourceDirectory} to your source directory, and FIXME to the comment that you want to search for.

Does anyone know a nice way to print out the files found in this fileset in the build file (other than just looking in Eclipse again)?

OTHER TIPS

Avoid the necessity. If you're placing code into a class that shouldn't be there in production, figure out how to do it differently. Provide a hook, say, so that the testing code can do what it needs to, but leave the testing code outside the class. Or subclass for testing, or use Dependency Injection, or any other technique that leaves your code valid and safe for production, while still testable. Many such techniques are well-documented in Michael Feathers' fantastic book, Working Effectively with Legacy Code.

Add a unit test that fails if the block is present. Maybe the block sets a global variable CODE_BLOCK_IS_NOT_DELETED = true; that the unit test checks for.

However, your bigger problem is that you test/develop with code that you don't need or use in production. That doesn't sound right.

One somehow dirty suggestion would be to create a class with a static method lets say

class Prod {
   public static void uction(){
   }
}

and then mark the places you want with

Prod.uction();

Then before production simply delete the class and you will get compiler errors where needed :D

However you technically solve this, I would recommend to do it the other way round: do not do something special for the production build but structure your code and build environment in such a way that the magic happens during the development build. The production build should be as foolproof (or Murphy proof) as possible.

If something goes wrong in the development build: so what.

Anything going wrong in the production build will hurt much more.

[edit:] Works for C++... :-)

Use these preprocessor defintions and all your problems will be solved:

#ifdef _DEBUG
#define COMMENT (code)  /* code */
#else
#define COMMENT (code) #error "Commented out code in release!"
#endif

Not sure if the syntax is entirely correct, but you get the idea.

We added a trigger to subversion that blocks \\NOCOMMIT: You could have a \\NODEPLOY: tag that your build script would look for before allowing a build.

TDD and Dependency Inversion concepts might help you here. By putting the code that varies into a class that implements an interface, you can control when the Test version of that code runs and when the prod version runs.

Then you have a file, clearly named as being for testing, that you can leave out of your build.

In projects I've worked on, I've had various tidbits of code that are in place to enable easy testing during development. I wrap these in an if block that checks a final boolean. When the boolean is true, the code can be accessed. When the boolean is false, I depend on the compiler removing the code from the resulting .class files as an optimization. For instance:

public class Test {
    public static void main(String[] args) {
        final boolean TESTABLE = true;

        if (TESTABLE) {
            // do something
        }
    }
}

Typically, I manage these variables on my own, using them during development and setting TESTABLE to false when I'm done. A development team could easily agree to a convention for variable names, like TESTABLE, and the build file's production target could check for and fail if any source files had a TESTABLE variable = true.

In addition to all the above suggestions (what's with all the manual crap and adding cruft to the code? automate things people...), I notice that you're using Eclipse, Spring, and ANT. Eclipse supports multiple source folders - separate your code out into a "source" and "testing" folder, put anything for production in the source folder and put anything "not production" in the testing folder. Spring allows you to have multiple configurations that reference different implementations - so you can have a production configuration that references classes only in production, and testing configuration(s) to run with your testing code. Have the ANT script build the production and testing versions of your app - for testing add the "testing" folder to your compile path, for production leave it off. If a class references a testing class from production you'll get a compile error - if a production Spring configuration references a class from testing in production, it will fail as soon as it tries to load it.

Maybe if you mark those classes/methods as depricated, then they would be flagged during compilation time?

For our production environments, we have a couple of simple C tools for stripping out sections using a very special comments. /*#BEGIN_SKIP*/ and /*#END_SKIP*/. Stick to standard C run-time, and you can compile on any environment.

You can change your entire build cycle to replicate the source code, transform it, and compile it.

I would try to avoid this as far as possible. - An alternative approach would be to use dependency injection to inject different implementations for testing.

Or...

Add an inTest boolean field to the objects and wrap the optional code in an if statement.

if(inTest) {
testMethod();
}

You could set this vboolean with dependency injection or read it from a passed in system property (-DinTest=true)

Hope this helps.

You can use a java preprocessor. For j2me applications I use antenna preprocessor. The code looks like this

public void someMethod() {
    //#ifdef DEBUG
    doDebugStuff();
    //#endif     
}

Eclipse allows for other markers than just //TODO, you can add, for example, //TOBEREMOVED and give it a high priority, so it shows up before all the other TODO markers.

Just add some //TODO: -- then make a c# script (cs-script.net) which looks for //TODO in your code and displays them. You can then add this script to your automated builds (if you're doing that), so each time you do a build, you can see what there is to do. Review your code's todo list before deploying.

Alternatively to writing your own script, there's some instructions on how to integrate vstudio with some tool that points out your todo lines as well: http://predicatet.blogspot.com/2006/12/show-all-tasks-in-visual-studion-2005-c.html

However, it seems to me, setting up that tool is more of a pain than writing a simple C# script with a regex.

I use the //FIXME keyword that eclipse displays, together with //TODO, in the Tasks View (you can filter what to see on it). You shouldn't go out to production if there is some //FIXME around :)

My solution is to work on two seperate branches of code. One production branch which only gets clean code without any debugging code and another (Sometimes I even have several of these) for testing, debugging, trying new struff etc.

In eclipse these are separate projects (or groups of projects).

Mercurial is a nice VCS for this type of work but CVS and subversion are good too.

The obvious way to solve this is to have a unit test that only runs on the build that is intended to build the files for production (or checks if the current build is targeted for production and runs the test if it is) and fail the build if the test fails.

You won't ever forget. In terms of what kind of test, ideally it would actually check for whatever the code does. If this is not possible, then a global static as Terry Lorber suggested would be a lot better than what you have now.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top