48

In C#, we have 2 modes to build projects : Debug and Release, I wonder if Java has the same thing. I am using IntelliJ IDEA as Java IDE and so far I haven't seen anywhere to configure a build mode like in VS IDE.

JatSing
  • 4,857
  • 16
  • 55
  • 65
  • did you search the web for something like **java using assert**? as for IDEA, if you look into /bin/idea.exe.vmoptions you'll most likely find that it runs in `Debug` mode itself - if there's `-ea` setting present :) – gnat Dec 23 '11 at 07:58
  • @gnat, yes, there's `-ea` setting in `idea.exe.vmoptions`. But how about when it builds an artifact (a jar file), still in `Debug` mode with a artifact ? – JatSing Dec 23 '11 at 08:07
  • 1
    in vmoptions file, `-ea` impacts how IDEA runs (it's a java application you know?) **not** the code it builds. As for the jars, you manage their mode in runtime by specifying or omitting `-ea`. As I wrote, just search web for java assert there are plenty tutorials on that – gnat Dec 23 '11 at 08:12

3 Answers3

39
javac 
  -g                         Generate all debugging info
  -g:none                    Generate no debugging info
  -g:{lines,vars,source}     Generate only some debugging info

You can choose to include debug symbols in the compiled classes (this is the default) or to not do so. There is not much benefit to not doing that. The jar files will be a little smaller, but the performance benefit is minimal (if any). Without these symbols you no longer get line numbers in stack traces. You also have the option to include additional symbols with local variable names (by default there are only source file names and line numbers).

java
    -ea[:<packagename>...|:<classname>]
    -enableassertions[:<packagename>...|:<classname>]
                  enable assertions

You can also enable assertions at run-time (default is off), which is sometimes useful during development and testing. This does have a performance impact (if the code in question did indeed make use of assertions, which I think is uncommon).

Regardless of any of these settings, the JVM always allows you to attach a debugger.

What Java does not have is conditional compilation where completely different code would be compiled based on some external setting. The closest you can get is something like public static final boolean DEBUG_BUILD = true; somewhere in your code and use that in if statements. This will actually make the compiler exclude code that becomes unreachable, but you have to set this constant in the source code.

Community
  • 1
  • 1
Thilo
  • 257,207
  • 101
  • 511
  • 656
  • 1
    anyway to make `public static final boolean DEBUG_BUILD` into preprocess, something like `#ifdebug` in C# ? – JatSing Dec 24 '11 at 03:38
  • 4
    @JatSing: Not directly. You could have some kind of script that updates the value before you start the compiler. Or maybe have a Constants.java and two versions of that, and setting the compile classpath for one of them. But nothing in the official toolchain. – Thilo Dec 25 '11 at 10:26
21

It is normal practice in Java to release everything is a manner which can be debugged. For some projects requiring obfuscation, they could have a release build, but I have never seen this in 12 years of developing Java.

Things such as assertions and debug messages are usually turned off at runtime for a production instance but can be turned on at any time (even dynamically) if required.

IMHO it is best practice to use the same build in every environment, not just the same source but the same JARs. This gives you the best chance that, if it works in test, it will work in production and if you have a problem in production, you can re-produce it in test.

As so much Java code is written this way, the JIT is very good at optimising dead code which is never called. So much so that IMHO most of the micro-"benchmarks" where Java out performs C++, is when the benchmark doesn't do any thing and the JIT is better at detecting this. IMHO, C++ assumes the developer is smart enough not to write code which doesn't do anything.

gnat
  • 6,213
  • 108
  • 53
  • 73
Peter Lawrey
  • 525,659
  • 79
  • 751
  • 1,130
  • 3
    "I have never seen this in 12 years of developing Java". To me, that is the most relevant part of your answer, as you are writing Java for HFT(!). Does that mean that compiling Java code to include all debugging info does /not/ interfere with the JVM JIT? I assume yes, but seek confirmation. – kevinarpe Mar 14 '16 at 06:50
  • 2
    For future readers, "HFT" = "High Frequency Trading". Really performance sensitive stuff :) – jocull Aug 21 '19 at 17:15
  • 1
    @kevinarpe Sorry about the slow reply. I haven't see any tuning benefit for removing debug information except reducing download times by making the JAR smaller. – Peter Lawrey Aug 23 '19 at 13:39
4

You're asking for different kinds of builds to compile in different things I guess. For example to have Debug.WriteLine and Console.WriteLine.

"No, Java doesn't have an exact match for that functionality. You could use aspects, or use an IOC container to inject different implementation classes." stole this from the following question: Conditional Java compilation

(there're other nice answers for you there)

Community
  • 1
  • 1
Akku
  • 4,373
  • 4
  • 48
  • 67