简体   繁体   中英

Sonar: Replace the synchronized class "Hashtable" by an unsynchronized one such as "HashMap"

Im having trouble replacing hashtable for hashmap because the method im using receives a hashtable:

private Context getInitialContext() throws NamingException {

        final Hashtable<String, Object> jndiProperties = new Hashtable<>();

        jndiProperties.put(Context.URL_PKG_PREFIXES, "org.jboss.ejb.client.naming");
        // This "new InitialContext()" receives a Hastable, and I can't modify that
        // because that is part of a jar
        // "javax.naming.InitialContext.InitialContext(Hashtable<?, ?> environment)
        // throws NamingException"
        context = new InitialContext(jndiProperties);

        return context;
    }

InitialContext method:

public InitialContext(Hashtable<?,?> environment)
        throws NamingException
    {
        if (environment != null) {
            environment = (Hashtable)environment.clone();
        }
        init(environment);
    }

What can I do to solve this codesmell??

If you must make SonarQube happy & use InitialContext consider using

Properties

See: https://docs.oracle.com/javase/8/docs/api/java/util/Properties.html

So instead of:

final Hashtable<String, Object> jndiProperties = new Hashtable<>();

Use:

final Properties jndiProperties = new Properties();

Note from the JavaDocs:

Because Properties inherits from Hashtable, the put and putAll methods can be applied to a Properties object. Their use is strongly discouraged as they allow the caller to insert entries whose keys or values are not Strings. The setProperty method should be used instead. If the store or save method is called on a "compromised" Properties object that contains a non-String key or value, the call will fail. Similarly, the call to the propertyNames or list method will fail if it is called on a "compromised" Properties object that contains a non-String key.

This means that your orginal code example should look like:

    private Context getInitialContext() throws NamingException {

    final Properties jndiProperties = new Properties();

    jndiProperties.setProperty(Context.URL_PKG_PREFIXES, "org.jboss.ejb.client.naming");
    // This "new InitialContext()" receives a Hastable, and I can't modify that
    // because that is part of a jar
    // "javax.naming.InitialContext.InitialContext(Hashtable<?, ?> environment)
    // throws NamingException"
    context = new InitialContext(jndiProperties);

    return context;
}

Since InitialContext actually requires a Hashtable (which is a bad API decision, but it was probably made way before Map was a thing in Java) there's really no way to avoid the Hashtable entirely. In this case suppressing the warning in sonar (or flagging it as either WontFix or false positive) is the appropriate reaction.

It is a surprise to see Sonar uses Hashtable in another complaint solution.

https://rules.sonarsource.com/java/type/Vulnerability/RSPEC-4433

SonarSource 在这里使用 Hashtable

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM