9

I am using a few Java classes like javax.Mail.Session and MessageDigest for a tool I am building.

I noticed that it was difficult assigning them properties because they were using String constants for that.

For example, for a Session object, you have to assign String key value pairs in a Property instance which is then used to create a Session. So if you want your session to log debugging messages, assign "smtp.mail.debug", "true" in the Property instance. Similarly, if you want your MessageDigest to use SHA, create the MessageDigest instance as MessageDigest.getInstance("SHA")

I am yet to figure out what to do and where to get the information if say I wanted to implement MessageDigest using MD5 / RC4 etc, or add another property to my Session object.

Wouldn't it be really better if public enums were exposed by these respective classes to assign properties ?

Would save programmers lot of searching time at least.

4
  • "Wouldn't it be really better if public enums were exposed by these respective classes to assign properties?" No! Commented Aug 3, 2014 at 23:59
  • 1
    totally agree with @Raymond. I think it only uses String as constants because of [1] backward compatibility with std libraries developed before the existence of Enum [2] lack of enum usage enforcement and [3] the only reason where using strings were acceptable, if these parameters can't be discovered on compile time. And it's even worse when you start using numeric AWT constants masked with |. Commented Aug 4, 2014 at 0:00
  • 4
    @Unihedron : Not asking for opinions unless you are going to back it up with reasoning. Commented Aug 4, 2014 at 0:05
  • 1
    There are three reasons: backwards compatibility, backwards compatibility, and backwards compatibility. Commented Aug 4, 2014 at 0:10

3 Answers 3

12

I can see 2 main reasons:

Backward compatibility

The two examples you give were already part of the API before enums got introduced in Java 1.5. There's many more cases like that out there.

Extensibility

Take a look at for example MessageDigest. The javadoc specifies:

Every implementation of the Java platform is required to support the following standard MessageDigest algorithms:

• MD5
• SHA-1
• SHA-256

This lets other java.security.Provider libraries provide MessageDigest implementations for other algorithms than the ones minimally required by the API. Listing only the default ones in a restrictive enum on the API level would limit extensibility.

The same goes for allowing other javax.mail.Provider implementations to support additional/custom properties in the case of mail session properties.

Sign up to request clarification or add additional context in comments.

4 Comments

Neither of these reasons are satisfactory. The same way String.getBytes("UTF-8") can accept String.getBytes(StandardCharsets.UTF_8), and you don't need to handle a possible UnsupportedEncodingException, similar mapping could (should!) be provided for MessageDigest.getInstance("MD5"). Having to do runtime checking of things that are known at compile-time is always wrong. Good libraries would help you avoid this.
@swalog Could or should additional mappings with corresponding methods be provided? Sure, but for the reasons outlined above, that will not invalidate the need for the string-based methods.
Agreed. I should have been clear that the reasons you provided satisfies the question. My criticism is towards the api. I wanted to point out that there there is no reason for not having constants to avoid runtime string look-up for implementations that are required by the api. We could have have that and backwards compatibility and extensibility.
@swalog StandardCharsets.UTF_8 contains the actual Charset implementation, so it can not fail in finding it, whereas a MessageDigest.getInstance(HypotheticalEnumType) still would have to go through the same code path as the string based based method to find a provider and only differ in not being allowed to throw a checked exception on failure.
2

This is likely due to the major focus of Java to provide backwards compatiablity to previous versions.

enum was introduced in Java 1.5, hence any API which was written against 1.4 or earlier will not provide support for this feature. This is very common amongst many of the APIs in the JDK

You also need to remember, enum is not extendable, meaning that if your wanted to introduce a new algorithm in the message digest, for example, you would be stuck...there'd be no way you could do it.

The same goes with the mail API, the mail API is provides support for distinctively different concepts, not all of them will have the same series of properties and would be impossible to devise a single enum capable of supporting ALL the various properties between different implementations that exist now or in the future, enum is just simply to inflexible for this job.

2 Comments

I have read about that. But they could have extended their API to allow using enums to assign properties, right ?
@Raymond232 That's not the point of those APIs though. Those APIs are designed to provide a common frontage through which you can interact with, in some cases, interfaces. Those interfaces would still be limited to been able to provide access to what they know, not what might come in the future...enum, in this context is to restrictive...
2

It will be to simple to think that reason is only backward compatibility.

For JavaMail because it has too many different settings related to different connectors and you only need some part of them to setup connection with one of supported protocols. Each connector is implemented in separate class and as I think, there is no reason to let for example, POP3 connector to know settings for IMAP connector.

For MessageDigest the reason is to support non-standard encryption algorithms, which is not packed with JDK but provided by 3rd party JCE adapters. For example how it will look for GOST algorithm provided by CryptoPro JCE:

  MessageDigest digest = MessageDigest.getInstance("GOST3411"); 

1 Comment

I agree with both your points, but I was looking for a more generic answer (in terms of general use of String constants). Anyways, thanks.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.