Setting a variable (NDEBUG) during compilation of a JDK 1.1 applet

A

A. Farber

Hello,

is there please a way to set a variable (like for example a
boolean NDEBUG) during the compilation of the classes?

I'd like to be able to compile a debug and a production version
of my applet by using the same GNU Makefile (gmake DEBUG=1)

Currently I have to edit the source code every time and change
the NDEBUG variable there. Here is the top of my Makefile,
I wish I could add smth. like "-D-JNDEBUG=false" there:

JAVAC = /usr/local/jdk1.3.1-linux/bin/javac
JFLAGS = -target 1.1 -encoding KOI8_R -J-Dfile.encoding=KOI8_R

ifeq ($(DEBUG),1)
JFLAGS += -g
endif

.......etc...........

Regards
Alex
 
O

Oliver Wong

A. Farber said:
Hello,

is there please a way to set a variable (like for example a
boolean NDEBUG) during the compilation of the classes?

I'd like to be able to compile a debug and a production version
of my applet by using the same GNU Makefile (gmake DEBUG=1)

Currently I have to edit the source code every time and change
the NDEBUG variable there. Here is the top of my Makefile,
I wish I could add smth. like "-D-JNDEBUG=false" there:

JAVAC = /usr/local/jdk1.3.1-linux/bin/javac
JFLAGS = -target 1.1 -encoding KOI8_R -J-Dfile.encoding=KOI8_R

ifeq ($(DEBUG),1)
JFLAGS += -g
endif

......etc...........

You could have your program accept a command line argument (e.g. via
public static void main(String[])), and set the NDEBUG variable based on
those arguments. This would set it at runtime rather than compile time
though.

- Oliver
 
D

Dimitri Maziuk

A. Farber sez:
Hello,

is there please a way to set a variable (like for example a
boolean NDEBUG) during the compilation of the classes?

I'd like to be able to compile a debug and a production version
of my applet by using the same GNU Makefile (gmake DEBUG=1)

Currently I have to edit the source code every time and change
the NDEBUG variable there. Here is the top of my Makefile,
I wish I could add smth. like "-D-JNDEBUG=false" there:

JAVAC = /usr/local/jdk1.3.1-linux/bin/javac
JFLAGS = -target 1.1 -encoding KOI8_R -J-Dfile.encoding=KOI8_R

ifeq ($(DEBUG),1)
JFLAGS += -g
endif

This is one of the things that's easier with ant: it has an
in-place replace, equivalent of
for i in `ls *.java`
do
cat $i | sed 's/boolean DEBUG=true;/boolean DEBUG=false;/g' > ${i}.tmp
mv ${i}.tmp $i
done

To answer your question, no, there is no other way.

Dima
 
T

Thomas Hawtin

A. Farber said:
is there please a way to set a variable (like for example a
boolean NDEBUG) during the compilation of the classes?

The simplest solution would be to use the simple assert facility provided.

Alternatively you could use a static final constant, or initialise a
static final variable from a system property.

Tom Hawtin
 
T

tom fredriksen

Oliver said:
A. Farber said:
is there please a way to set a variable (like for example a
boolean NDEBUG) during the compilation of the classes?

I'd like to be able to compile a debug and a production version
of my applet by using the same GNU Makefile (gmake DEBUG=1)

You could have your program accept a command line argument (e.g. via
public static void main(String[])), and set the NDEBUG variable based on
those arguments. This would set it at runtime rather than compile time
though.

The OP has a perfectly reasonable question actually. What one wants, in
some circumstances, is to have blocks of code which should only be
included in the classes if the environment variable is set. F.ex testing
code or other things. While if the variable is not set, the code is not
included at all. It allows you to make code for different but similar
uses. This is very normal in C systems.

Is there a way to do this in java or does it not have any way of reading
such environment variables for such purposes? hmm... actually that
specific example would require a preprocessor of sorts. But it would
still be interesting to be able to communicate such compile time
decisions to the class. Still possible? or did I just answer my own
question?

/tom
 
A

A. Farber

Thanks Tom, but the problem is that I have to use JDK 1.1
and applet (not application) for my little card game.

What system property that I could (ab)use do you mean?
I get a security exception when calling getProperty("NDEBUG")

Regards
Alex
 
J

James Westby

tom said:
Oliver said:
A. Farber said:
is there please a way to set a variable (like for example a
boolean NDEBUG) during the compilation of the classes?

I'd like to be able to compile a debug and a production version
of my applet by using the same GNU Makefile (gmake DEBUG=1)


You could have your program accept a command line argument (e.g.
via public static void main(String[])), and set the NDEBUG variable
based on those arguments. This would set it at runtime rather than
compile time though.


The OP has a perfectly reasonable question actually. What one wants, in
some circumstances, is to have blocks of code which should only be
included in the classes if the environment variable is set. F.ex testing
code or other things. While if the variable is not set, the code is not
included at all. It allows you to make code for different but similar
uses. This is very normal in C systems.

Is there a way to do this in java or does it not have any way of reading
such environment variables for such purposes? hmm... actually that
specific example would require a preprocessor of sorts. But it would
still be interesting to be able to communicate such compile time
decisions to the class. Still possible? or did I just answer my own
question?

/tom

How about using patch (I'd do it with ANT integration) to change the
flag within the appropriate files?

Far from ideal I know, but it might be acceptable in this simple case.


James
 
R

Roedy Green

Is there a way to do this in java or does it not have any way of reading
such environment variables for such purposes?

In one early Java project I did we used the C preprocessor itself for
macro work. The problem was every time we ran it, it regenerated all
the Java which meant a global recompile, in pre-ant days that took
hours.

Today you could use the technique then use Untouch to redate the Java
files that did not really change.

See http://mindprod.com/jgloss/preprocessor.html for a list of
possibilities.
 
T

Thomas Hawtin

A. Farber said:
Thanks Tom, but the problem is that I have to use JDK 1.1
and applet (not application) for my little card game.

I would suggest specifying a later version. On average around five
security bugs, of various degrees of severity, are found in Java
Standard Edition each year. Even 1.3 will finish its end-of-life period
this year, and presumably wont receive security updates after that.
What system property that I could (ab)use do you mean?
I get a security exception when calling getProperty("NDEBUG")

From an applet, applet parameters would be appropriate (although they
shouldn't be assigned to static fields).

http://download.java.net/jdk6/docs/api/java/applet/Applet.html#getParameter(java.lang.String)

Tom Hawtin
 
O

Oliver Wong

tom fredriksen said:
Oliver said:
A. Farber said:
is there please a way to set a variable (like for example a
boolean NDEBUG) during the compilation of the classes?

I'd like to be able to compile a debug and a production version
of my applet by using the same GNU Makefile (gmake DEBUG=1)

You could have your program accept a command line argument (e.g. via
public static void main(String[])), and set the NDEBUG variable based on
those arguments. This would set it at runtime rather than compile time
though.

The OP has a perfectly reasonable question actually. What one wants, in
some circumstances, is to have blocks of code which should only be
included in the classes if the environment variable is set. F.ex testing
code or other things. While if the variable is not set, the code is not
included at all. It allows you to make code for different but similar
uses. This is very normal in C systems.

I did not mean to imply that the OP's request was unreasonable. I missed
the part where (s)he said "applet" though, so the command line argument
won't work. As Thomas Hawtin proposed, applet parameters would work better.
Is there a way to do this in java or does it not have any way of reading
such environment variables for such purposes? hmm... actually that
specific example would require a preprocessor of sorts. But it would still
be interesting to be able to communicate such compile time decisions to
the class. Still possible? or did I just answer my own question?

The question is whether or not it's possible to affect the behaviour of
the compiler (e.g. affecting what code it emits), without changing the the
source code. The answer depends completely on the compiler! AFAIK, Sun's
javac compiler doesn't have any pre-processor support, but there do exist
3rd party "java preprocessors" out there (I'm assuming the link Roedy posted
contains some examples), and there's nothing preventing you from writing
your own preprocessor.

I just thought that this latter solution would be overkill if it were
possible to solve the problem with a command line argument (or applet
parameter). For the purposes of setting a flag, I figured the command line
argument/applet parameter solution would be "good enough".

- Oliver
 
M

Mitch

Thomas said:
I would suggest specifying a later version. On average around five
security bugs, of various degrees of severity, are found in Java
Standard Edition each year. Even 1.3 will finish its end-of-life period
this year, and presumably wont receive security updates after that.


From an applet, applet parameters would be appropriate (although they
shouldn't be assigned to static fields).

http://download.java.net/jdk6/docs/api/java/applet/Applet.html#getParameter(java.lang.String)


Tom Hawtin
Now I am young and naive so am sure this hasn't been mentioned for good
reason

if( debug == true )
{
do debug stuff
}

now my question is why? are you referring to a method of debugging that
involves the ide in some way (breakpoints etc) that you can do with
other languages / ides etc that you cant with java. What am I missing?
You learn a lot from others questions but sometimes you just can't
keep up :)
 
O

Oliver Wong

Mitch said:
Now I am young and naive so am sure this hasn't been mentioned for good
reason

if( debug == true )
{
do debug stuff
}

now my question is why? are you referring to a method of debugging that
involves the ide in some way (breakpoints etc) that you can do with other
languages / ides etc that you cant with java. What am I missing? You
learn a lot from others questions but sometimes you just can't keep up :)

Why what? Is your question "Why don't you do that?" or is it "Why did
you do that?" or something else?

I suspect that the variable that the OP is referring to as "NDEBUG"
pretty much serves exactly the purpose of your "debug" variable. The OP's
question, I believe, is whether it was possible to set the value of this
variable at compile time, perhaps via command line arguments passed to a
compiler (or the thing that's processing the make file).

- Oliver
 
M

Mitch

Oliver said:
Why what? Is your question "Why don't you do that?" or is it "Why did
you do that?" or something else?

My question was more along the lines of "Is it ok to do that?". Most of
the reading I have done on debugging turns me against flooding code with
println's etc. and tries to encourage the use of the IDE's debug features.
I suspect that the variable that the OP is referring to as "NDEBUG"
pretty much serves exactly the purpose of your "debug" variable. The
OP's question, I believe, is whether it was possible to set the value of
this variable at compile time, perhaps via command line arguments passed
to a compiler (or the thing that's processing the make file).

- Oliver

Also I asked my question because I wasn't sure if this was what the OP
meant, or if he was referring to an IDE debug feature I had yet to come
across (There has to be hundreds).

Mitch.
 
O

Oliver Wong

Mitch said:
My question was more along the lines of "Is it ok to do that?". Most of
the reading I have done on debugging turns me against flooding code with
println's etc. and tries to encourage the use of the IDE's debug features.

Don't use println's (I'm presuming you mean println calls on System.out
or System.err) for logging. Instead, try to learn how to use Java's logging
API. There's a tutorial from Sun at
http://java.sun.com/j2se/1.4.2/docs/guide/util/logging/overview.html but
it's a bit difficult to read (in my opinion anyway).

But logging should be used for recording what's going on. If you're
writing a web server, for example, your user might want it to record every
request that was made for statistical purposes. Or if something "funny"
happens, you might want to log that so that someone can look over it later
to check for security breaches. If an error happens, you might want to
produce a log that the user can e-mail into you so that you can try to
figure out what the problem was, without asking the user to manually try to
replicate the problem.

For debugging, you should definitely use a debugger. It allows you to
step through the program one line at a time, and inspect the contents of
variables at any point in the program, which largely eliminates the need for
println statements that are only used for debugging.

- Oliver
 
R

Roedy Green

now my question is why? are you referring to a method of debugging that
involves the ide in some way (breakpoints etc) that you can do with
other languages / ides etc that you cant with java

you can do breakpoint debugging of Java apps and Applets in an IDE
like Eclipse or IntelliJ.
 
R

Roedy Green

My question was more along the lines of "Is it ok to do that?". Most of
the reading I have done on debugging turns me against flooding code with
println's etc. and tries to encourage the use of the IDE's debug features.

the one thing unusual about java is

static final boolean debug = false;


if ( debug )
{
stuff;
}

generates zero code. It is all eliminated at compile time.

Granted it clutters your source code, but it does not clutter the
executable.
 
A

A. Farber

the one thing unusual about java is
static final boolean debug = false;
if ( debug )
{
stuff;
}
generates zero code. It is all eliminated at compile time.

Ok, good to know. Too bad java doesn't allow a "javac -J-Ddebug=true"
command line option to set that variable in a C-way.

And Java-asserts can't be used in my project (a little multiplayer
card game applet at http://preferans.de ) because I want to stick
with JDK 1.1 and even with the old MS Java VM (I want my game
to run everywhere and I don't care about security/bugs/newest java
of the week - if my visitors don't care :)

So I think I'll add some sed/perl inplace-editing into my Makefile

Regards
Alex
 
C

Chris Uppal

A. Farber said:
is there please a way to set a variable (like for example a
boolean NDEBUG) during the compilation of the classes?

Yes there is, if your build process is flexible enough to allow it.

It's easier to describe if we approach it in small steps.

First off, imagine that you have a utility class:

public class CompileTimeSettings
{
public static final Boolean DEBUG = true;

// .. other settings...
}

If you include that in your build then the constant will be evaluated at
compile time, and its value embedded directly into the generated bytecode
wherever any other code refers to:
CompileTimeSettings.DEBUG
(and the 1.4 and 1.5 compilers from Sun[*] will remove any resulting
unreachable code).

([*] Perhaps other compilers will do too, but I don't know myself.)

But that doesn't relieve you of the necessity to change the code each time you
change the setting. So the next step is to have two separate definitions of
that class. Neither is kept in the same area as the rest of your Java source
files, and instead you change the build paths to include one or the other when
you compile. You can probably do that from within your Makefile based only on
command-line flags (I don't know enough about GNU make to be sure).

Then the last step is instead of having one or more alternative versions of
CompileTimeSettings.java, to scrap the lot and always generate the source as
part of each build. Your Makefile would then include a dependency to rebuild
that file by invoking a helper program (written in /bin/sh, Ruby, or whatever
else takes your fancy) which uses the values of its command line flags to
generate appropriate source.

It's up to you to decide whether your need for build-time constants (or rather
variables), is great enough to justify the extra complexity.

-- chris
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,768
Messages
2,569,574
Members
45,048
Latest member
verona

Latest Threads

Top