dev@glassfish.java.net

Re: should constants be used in a modularized system?

From: Kedar Mhaswade <Kedar.Mhaswade_at_Sun.COM>
Date: Fri, 21 Mar 2008 11:03:51 -0700

I agree that this is largely up to our module update/patch
policy, which needs to be carefully thought through.
I don't think we have said what happens after a particular
release of app-server that depends on the module system. How
to "upgrade" or "patch" a particular module in an installation
of app-server is not known.

One may say that you can rely on version and jar file in
modules folder, but that's hardly sufficient. In general,
this applies to all public interface of a module, not
just constants.

- Kedar

Lloyd L Chambers wrote:
> Ken,
>
> I'm not sure if the example of using a variable with a static{...} block
> has the same effect as simply declaring the variable. Presumably it is
> different, but the JDK could be too smart for its own good.
>
> Regarding a recommendation, this is more difficult. Kedar's email
> suggests that he thinks it might not be a problem...or might be.
>
> My assumption is that in a highly modular system, users expect to be
> able to swap out modules quickly and easily, and that modules might
> change their constants (maybe a pool size or default port or whatever).
> Will problems be rare? Probably. Will they be minor? Possibly not.
> I don't know those answers.
>
> At this point I think it boils down to developer intent: should the
> value of constant 'X' be runtime-current or compile-time current? I
> think in most cases one will expect runtime-currency and therefore the
> get() style is more appropriate, albeit a weird change in working habits.
>
> Since we build most modules together, we might easily dismiss this as an
> issue. But what happens when we start patching by shipping new versions
> of modules that 3rd-parties depend on and/or when 3rd parties start
> plugging in many different modules? I don't know, but it makes me a bit
> uneasy.
>
> Lloyd
>
> On Mar 21, 2008, at 12:19 AM, Ken Paulsen wrote:
>>
>> Lloyd, Bill and others:
>>
>> To make sure I understand correctly, let me see if I can repeat back
>> what you're saying...
>>
>> If you define a constant (public static final), for example:
>>
>> public static final String C = "hello";
>>
>> ...then another class references that code, it will be contained in
>> bytecode (i.e. it won't look at the orginal C). In other words, if
>> you change "hello" to "goodbye" w/o recompiling all classes using C,
>> you'll still have "hello" in those classes that weren't recompiled.
>>
>> However... if you define your "constant" like this:
>>
>> private static String getC() { return "hello" }
>> public static final String C = getC();
>>
>> Or even:
>>
>> public static final String C;
>> static { C = "hello"; }
>>
>> Then code refering to "C" *WILL* refer back to the class instead of
>> keeping it local via bytecode. This is arguably not a constant now
>> (although public static final, it cannot be "inlined" by other .class
>> code). In other words, if you change "hello" to "goodbye" and ONLY
>> compile the class which defines C, it will still be seen in ALL
>> classes referencing C (i.e. no more "hello" anywhere).
>>
>> Is that right? And if so, what is your recommendation or design
>> pattern that we should follow? It was not clear (to me) from the
>> email exchange. Which if these should be preferred:
>>
>> * Enum
>> * "public static final" initialized via a static method
>> * "public static final" initialized via a static block (probably the
>> same thing to the JVM??)
>> * No "public static final" use static getter method instead
>> * or ??
>>
>> Thanks for bringing this up... this is one of those little things that
>> could cause big problems. :)
>>
>> Ken
>>
>> Lloyd L Chambers wrote:
>>> Bill,
>>>
>>> Agreed...though problem with enums for management (JMX) include:
>>>
>>> - they require a new class that might not be available on a client
>>> (across "the wire")
>>> - they might not map automatically to other non-Java protocols
>>>
>>> At least that's my understanding.
>>>
>>> So for values returned across the wire through a management
>>> interface, enums are an issue. A good example of this is
>>> java.util.logging.Level; I ran into this problem recently working
>>> with a developer on a JMX adapter.
>>>
>>> Lloyd
>>>
>>> On Mar 20, 2008, at 2:31 PM, Bill Shannon wrote:
>>>> Lloyd L Chambers wrote:
>>>>> In Glassfish V3 the system is highly modularized. Compiling one
>>>>> module against another might mean using static constants eg:
>>>>> // module B using org.glassfish.foo.bar from another module A
>>>>> import org.glassfish.foo.bar.CONSTANT1;
>>>>> ...
>>>>> doSomething( CONSTANT1 );
>>>>> ...
>>>>> If I understand correctly, java constants are compiled into the
>>>>> resulting bytecode.
>>>>> So if the constant is later changed in the defining module, code
>>>>> compiled against that module does *not* pick up the new value
>>>>> unless it is recompiled.
>>>>> In short, in a modular system, should constant values be fixed at
>>>>> compile time, or picked up dynamically at runtime? If they are to
>>>>> be dynamic, then our constants need to be written as methods eg:
>>>>> public static String getCONSTANT1();
>>>>> *not*
>>>>> public static final String CONSTANT1 = "val"
>>>>> Of course, there might not be a hard and fast rule. But if a
>>>>> module is newly-built and has new values for its constants, it
>>>>> might be reasonable to expect dependent modules to use the new values.
>>>>
>>>> Yes, we should all understand this. Primitives and String constants
>>>> are stored by *value*, not name. Once you choose a value for one of
>>>> these constants in a public API (across module boundaries), you're
>>>> committing to it, no matter what name you might use.
>>>>
>>>> Many of these constants should probably be enums, which don't have this
>>>> problem.
>>>>
>>>> String constants should really only be used for things that are
>>>> externally
>>>> defined and really won't change. Otherwise, if it can change, it's not
>>>> really a constant! :-)
>>>>
>>>> ---------------------------------------------------------------------
>>>> To unsubscribe, e-mail: dev-unsubscribe_at_glassfish.dev.java.net
>>>> For additional commands, e-mail: dev-help_at_glassfish.dev.java.net
>>>>
>>>
>>> ---
>>> Lloyd L Chambers
>>> lloyd.chambers_at_sun.com
>>> Sun Microsystems, Inc
>>>
>>>
>>>
>>>
>>> ---------------------------------------------------------------------
>>> To unsubscribe, e-mail: dev-unsubscribe_at_glassfish.dev.java.net
>>> For additional commands, e-mail: dev-help_at_glassfish.dev.java.net
>>>
>
> ---
> Lloyd L Chambers
> lloyd.chambers_at_sun.com <mailto:lloyd.chambers_at_sun.com>
> Sun Microsystems, Inc
>
>
>