Search code examples
talend

Talend - The import org.apache cannot be resolved


I've created a custom Talend component, which at certain step connects to an external Http service. For that, I'm using org.apache.commons.httpclient through javajet imports. I've seen the modules already exist in the Modules view. Nevertheless, when running a job the console outputs:

Execution failed : Failed to generate code.
[----------
1. ERROR in /Users/frb/Downloads/TOS_DI-20160510_1709-V6.2.0/workspace/.JETEmitters/src/org/talend/designer/codegen/translators/ngsi/orion/TOrionAppendBeginJava.java (at line 14)
    import org.apache.commons.httpclient.*;
           ^^^^^^^^^^
The import org.apache cannot be resolved
----------
2. ERROR in /Users/frb/Downloads/TOS_DI-20160510_1709-V6.2.0/workspace/.JETEmitters/src/org/talend/designer/codegen/translators/ngsi/orion/TOrionAppendBeginJava.java (at line 15)
    import org.apache.commons.httpclient.methods.*;
           ^^^^^^^^^^
The import org.apache cannot be resolved
----------
3. ERROR in /Users/frb/Downloads/TOS_DI-20160510_1709-V6.2.0/workspace/.JETEmitters/src/org/talend/designer/codegen/translators/ngsi/orion/TOrionAppendBeginJava.java (at line 16)
    import org.apache.commons.httpclient.params.HttpMethodParams;;
           ^^^^^^^^^^
The import org.apache cannot be resolved
----------
3 problems (3 errors)
]

Any hints about how to fix this issue? My Talend version is 6.2.0.

EDIT 1

This is my begin code:

<%@ jet 
    imports="
        org.talend.core.model.process.INode 
        org.talend.core.model.process.ElementParameterParser 
        org.talend.core.model.metadata.IMetadataTable 
        org.talend.core.model.metadata.IMetadataColumn 
        org.talend.core.model.process.IConnection
        org.talend.core.model.process.IConnectionCategory
        org.talend.designer.codegen.config.CodeGeneratorArgument
        org.talend.core.model.metadata.types.JavaTypesManager
        org.talend.core.model.metadata.types.JavaType
        java.util.List
        java.util.Map
        org.apache.commons.httpclient.*
        org.apache.commons.httpclient.methods.*
        org.apache.commons.httpclient.params.HttpMethodParams
    " 
%>
<% 
    // Get the CID
    CodeGeneratorArgument codeGenArgument = (CodeGeneratorArgument) argument;
    INode node = (INode)codeGenArgument.getArgument();
    String cid = node.getUniqueName();

    // Get the component parameters
    String orionEndpoint = ElementParameterParser.getValue(node, "__ORION_ENDPOINT__");
    String authEndpoint = ElementParameterParser.getValue(node, "__AUTH_ENDPOINT__");
    String authUsername = ElementParameterParser.getValue(node, "__AUTH_USERNAME__");
    String authPassword = ElementParameterParser.getValue(node, "__AUTH_PASSWORD__");
    String entityIdField = ElementParameterParser.getValue(node, "__ENTITY_ID_FIELD__");
    String entityTypeField = ElementParameterParser.getValue(node, "__ENTITY_TYPE_FIELD__");
    String defaultEntityType = ElementParameterParser.getValue(node, "__DEFAULT_ENTITY_TYPE__");
    String ignoredFilds = ElementParameterParser.getValue(node, "__IGNORED_FIELDS__");
%>
    System.out.println("I am the begin section");
    HttpClient client = new HttpClient();
    PostMethod method = new PostMethod(<%=authEndpoint%>);
    method.setRequestHeader(new Header("Content-Type", "application/json"));
    method.setRequestBody("{\"username\":\"" + <%=authUsername%> + "\",\"password\":\"" + <%=authPassword%> + "\"}");

    try {
        int statusCode = client.executeMethod(method);

        if (statusCode != HttpStatus.SC_OK) {
            System.err.println("Method failed: " + method.getStatusLine());
        } // if

        byte[] responseBody = method.getResponseBody();
        System.out.println(new String(responseBody));
    } catch (HttpException e) {
      System.err.println("Fatal protocol violation: " + e.getMessage());
      e.printStackTrace();
    } catch (IOException e) {
      System.err.println("Fatal transport error: " + e.getMessage());
      e.printStackTrace();
    } finally {
      method.releaseConnection();
    } // try

EDIT 2
I've added the following to my Component Descriptor file:

<IMPORTS>
  <IMPORT
    NAME="commons-httpclient"
    MODULE="commons-httpclient-3.1.jar"
    REQUIRED="true"
  />
</IMPORTS>

Now, in the modules view I'm able to see the following:

enter image description here

Sadly, the component outputs the same errors.

EDIT 3
After removing the imports and using fully qualified names, as suggested by @Balazs Gunics, the code seems to be generated. Nevertheless, some other errors related to commons-httpclient arise at running time:

Starting job job_tOrionAppend at 08:20 21/06/2016.
[statistics] connecting to socket on port 3916
[statistics] connected
I am the begin section
Exception in thread "main" java.lang.NoClassDefFoundError: org/apache/commons/logging/LogFactory
    at org.apache.commons.httpclient.HttpClient.<clinit>(HttpClient.java:66)
    at iotp_talend_connectors.job_torionappend_0_1.job_tOrionAppend.tMysqlInput_1Process(job_tOrionAppend.java:854)
    at iotp_talend_connectors.job_torionappend_0_1.job_tOrionAppend.tMysqlConnection_1Process(job_tOrionAppend.java:422)
    at iotp_talend_connectors.job_torionappend_0_1.job_tOrionAppend.runJobInTOS(job_tOrionAppend.java:1355)
    at iotp_talend_connectors.job_torionappend_0_1.job_tOrionAppend.main(job_tOrionAppend.java:1212)
Caused by: java.lang.ClassNotFoundException: org.apache.commons.logging.LogFactory
    at java.net.URLClassLoader$1.run(URLClassLoader.java:372)
    at java.net.URLClassLoader$1.run(URLClassLoader.java:361)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.net.URLClassLoader.findClass(URLClassLoader.java:360)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
    at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:308)
[statistics] disconnected
[statistics] disconnected
    at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
    ... 5 more
Job job_tOrionAppend ended at 08:20 21/06/2016. [exit code=1]

Solution

  • So in the begin.javajet code of yours the following code will only import these libraries for the code generation itself. But you need them to the generated code. Generating java using java makes it hard to oversee this.

    <%@ jet 
        imports="
        org.apache.commons.httpclient.*
        org.apache.commons.httpclient.methods.*
        org.apache.commons.httpclient.params.HttpMethodParams
    

    So what you need is to have these imports added to the generated code. Well that is not really possible :( https://www.talendforge.org/forum/viewtopic.php?id=3670 To do that you need to modify the xml descriptor for your component. So your imports are right. All you have to do is make sure you use the fully qualified names. I.e.: This piece of code:

    System.out.println("I am the begin section");
    HttpClient client = new HttpClient();
    PostMethod method = new PostMethod(<%=authEndpoint%>);
    

    Have to be rewritten to look like this:

    System.out.println("I am the begin section");
    org.apache.commons.httpclient.HttpClient client =
       new org.apache.commons.httpclient.HttpClient();
    org.apache.commons.httpclient.methods.PostMethod method = 
       new org.apache.commons.httpclient.methods.PostMethod(<%=authEndpoint%>);
    

    Yes, it would be way more elegant if we could import the classes and use them.