Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there any way to define a constant value to Java at compile time

Tags:

java

c++

c

When I used to write libraries in C/C++ I got into the habit of having a method to return the compile date/time. This was always a compiled into the library so would differentiate builds of the library. I got this by returning a #define in the code:

C++:

#ifdef _BuildDateTime_
   char* SomeClass::getBuildDateTime() {
      return _BuildDateTime_;
   }
#else
   char* SomeClass::getBuildDateTime() {
      return "Undefined";
   }
#endif

Then on the compile I had a '-D_BuildDateTime_=Date' in the build script.

Is there any way to achieve this or similar in Java without needing to remember to edit any files manually or distributing any seperate files.

One suggestion I got from a co-worker was to get the ant file to create a file on the classpath and to package that into the JAR and have it read by the method.

Something like (assuming the file created was called 'DateTime.dat'):

// I know Exceptions and proper open/closing 
// of the file are not done. This is just 
// to explain the point!
String getBuildDateTime() {
    return new BufferedReader(getClass()
            .getResourceAsStream("DateTime.dat")).readLine();
}

To my mind that's a hack and could be circumvented/broken by someone having a similarly named file outside the JAR, but on the classpath.

Anyway, my question is whether there is any way to inject a constant into a class at compile time

EDIT

The reason I consider using an externally generated file in the JAR a hack is because this is) a library and will be embedded in client apps. These client apps may define their own classloaders meaning I can't rely on the standard JVM class loading rules.

My personal preference would be to go with using the date from the JAR file as suggested by serg10.

like image 423
GKelly Avatar asked Sep 19 '08 11:09

GKelly


People also ask

How do you assign a constant value in Java?

To make any variable a constant, we must use 'static' and 'final' modifiers in the following manner: Syntax to assign a constant value in java: static final datatype identifier_name = constant; The static modifier causes the variable to be available without an instance of it's defining class being loaded.

Can we declare constant in Java?

To turn an ordinary variable into a constant, you have to use the keyword "final." As a rule, we write constants in capital letters to differentiate them from ordinary variables. If you try to change the constant in the program, javac (the Java Compiler) sends an error message.

What are compile-time constants in Java?

4.1. Compile-Time Constants. A Java variable is a compile-time constant if it's of a primitive type or String, declared final, initialized within its declaration, and with a constant expression. Strings are a special case on top of the primitive types because they are immutable and live in a String pool.

Is constant compile-time?

A compile-time constant is a value that is computed at the compilation-time. Whereas, A runtime constant is a value that is computed only at the time when the program is running. 2. A compile-time constant will have the same value each time when the source code is run.


1 Answers

I would favour the standards based approach. Put your version information (along with other useful publisher stuff such as build number, subversion revision number, author, company details, etc) in the jar's Manifest File.

This is a well documented and understood Java specification. Strong tool support exists for creating manifest files (a core Ant task for example, or the maven jar plugin). These can help with setting some of the attributes automatically - I have maven configured to put the jar's maven version number, Subversion revision and timestamp into the manifest for me at build time.

You can read the contents of the manifest at runtime with standard java api calls - something like:

import java.util.jar.*;

...

JarFile myJar = new JarFile("nameOfJar.jar");    // various constructors available
Manifest manifest = myJar.getManifest();
Map<String,Attributes> manifestContents = manifest.getAttributes();

To me, that feels like a more Java standard approach, so will probably prove more easy for subsequent code maintainers to follow.

like image 51
serg10 Avatar answered Sep 25 '22 21:09

serg10