Salesforce wsc hacking: removing compiler warnings

I hate compiler warnings. These little yellow warning signs in Eclipse annoys me. I will go far to avoid compiler warnings in my own code.

But what about generated code? Actually generated code is the worst as it does not make sense to correct the code to remove the warnings – they will reappear when the code is regenerated. And it demonstrates sloppiness in the code generation tool.

In this article I will work through and demonstrate how to remove the compiler warnings from the wsc generated code, and some of the infrastructure code as well.

EnterpriseConnection and PartnerConnection

This generated class contains 2 kinds of compiler warnings:

  • In the logout() method, the __response local variable is never read.
  • Static knownHeaders Map references raw Class type.

The first warning actually covers another issue: the __response local variable is always initialized to an empty new constructed instance in every method. This is not necessary because the variable is always assigned to the result of a soap request. It should be initialized to null to avoid unnecessary object creations.

The corresponding connection.template file has a simple common template for all operations, and we do not want to introduce too many alterations. So we keep the __response local variable but initializes it to null. If the method return type is void we know this variable will not be read and therefore add a @SuppressWarnings("unused") to the variable declaration.

89
90
    <% if ("void".equals(gen.returnType(op))) { %>@SuppressWarnings("unused")<% } %>
    <%=gen.responseType(op)%> __response = null;

The second warning is fixed by simply adding a <?> to the Class type in the declaration of the knownHeaders static HashMap:

135
private static final HashMap<QName, java.lang.Class<?>> knownHeaders = new HashMap<QName, java.lang.Class<?>>();

Now the generated EnterpriseConnection (and PartnerConnection) are without compiler warnings. But we have introduced an error: the SoapConnection.setKnownHeaders() method called in the private newConnection() method is no longer compatible with the proper typed HashMap. We need to do some fixing in SoapConnection.

This class suffers from the raw Class type in lots of different places. Fixing these warnings also fixes the problem with the setKnownHeaders() method call from the EnterpriseConnection/PartnerConnection.

This class also has a warning from a missing serialVersionUID in the private class SessionTimedOutException (I do not like this class, it looks like control flow by exception which should be avoided. This we fix in another article).

Faults

Next on my list are the generated fault-types. They all suffer from missing serialVersionUID. They are all generated by special instantiations of the type.template. It appears that the corresponding generator (com.sforce.ws.tools.ComplexTypeGenerator) already has special treatment for base Fault types. A minor refactoring of the ComplexTypeGenerator where an isFault() public method is used to determine if the type being generated is a fault, and some cooperation in the type.template enables the serialVersionUID.

ComplexTypeGenerator:

64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
    public String baseClass() {
        StringBuilder sb = new StringBuilder();
 
        if (complexType.getBase() == null) {
            if (complexType.isHeader()) {
                sb.append("extends com.sforce.ws.bind.SoapHeaderObject ");
            } else if (isFault()) {
                sb.append("extends com.sforce.ws.SoapFaultException ");
            }
            sb.append("implements com.sforce.ws.bind.XMLizable");
        } else {
            sb.append("extends ").append(localJavaType(complexType.getBase(), 1, false));
        }
        return sb.toString();
    }
 
    public boolean isFault() {
        return getClassName().endsWith("Fault");
    }

type.template:

7
<% if (gen.fault) { %>  private static final long serialVersionUID = 1L;<% } %>

The Partner SObject

This Partner version of the SObject class contains a few unused imports. It appears that this is generated from the sobject.template. Removing the unused imports is easily done by just modifying the template. This does not seem to affect the Enterprise SObject

AggregateResult

This class also contains a few unused imports. It appears that this is generated from the aggregateResult.template. Removing the unused imports is easily done by just modifying the template.

JdkHttpTransport

Now that we are at it we might as well fix the single warning (raw types…) in the com.sforce.ws.transport.JdkHttpTransport class:

233
234
235
236
237
for (Map.Entry<String, List<String>> header : headers.entrySet()) {
    config.getTraceStream().print(header.getKey());
    config.getTraceStream().print("=");
    config.getTraceStream().println(header.getValue());
}

Source attached: wsc-hack-warnings-1.zip.

I have been through most of the other classes in the tool and removed most compiler warnings. Consider attached: wsc-hack-warnings-2.zip

Added as issue 66 to WSC.

About Jesper Udby

I'm a freelance computer Geek living in Denmark with my wife and 3 kids. I've done professional software development since 1994 and JAVA development since 1998.
This entry was posted in Java, Salesforce and tagged , , , . Bookmark the permalink.

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.