使用java中的processbuilder执行sqoop命令

时间:2016-10-25 12:55:16

标签: java shell processbuilder sqoop

我有一个工作的sqoop命令,可以将数据从oracle导入到hive。 当我尝试使用流程构建器API运行sqoop命令时,它正在提供

  

java.io.IOException:error = 2,没有这样的文件或目录

从shell执行命令时,同样的命令没有任何问题。请让我知道如何解决这个问题。

我还尝试将命令拆分为字符串数组以及字符串列表。但是,这两种方法都不起作用。

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.List;


public class SqoopTest {
    static ProcessBuilder processBuilder = null;
    static Process spawnProcess = null;
    static int exitValue;
    static int pid;
    static List<String> commands;

    public static void main(String[] args) {

      runSqoop();



    }

    /*
     * Executes the shell script with a series of sqoop commands.
     * 
     * 
     * 
     * sqoop import -D mapred.child.java.opts='\-Djava.security.egd=file:/dev/../dev/urandom' 
     * --connect 'jdbc:oracle:thin:@(DESCRIPTION=(ADDRESS_LIST=(LOAD_BALANCE=ON)(FAILOVER=ON)(ADDRESS=(PROTOCOL=TCP)(HOST=173.37)(PORT=1541))(ADDRESS=(PROTOCOL=TCP)(HOST=173.37)(PORT=1541)))(CONNECT_DATA=(SERVICE_NAME=CAFI2PRD)(SERVER=DEDICATED)))' 
     * --username XXCSS_O --password "c******3" --split-by LINE_ITEM_ID -m 10 
     * --query "select LINE_ITEM_ID,LIST_PRICE,SERVICE_VALUE from XXCSS_KTN_REQ_LINE_DETAIL where \$CONDITIONS AND lid_date > to_date('2016-10-13 03:04:18','MM/dd/yyyy hh24:mi:ss') and lid_date <= to_date('2016-10-13 03:04:18','MM/dd/yyyy hh24:mi:ss')" 
     * --map-column-hive LINE_ITEM_ID=BIGINT,LIST_PRICE=BIGINT,SERVICE_VALUE=BIGINT 
     * --null-string '\\\\N' --null-non-string '\\\\N' --hcatalog-home 
     * /opt/mapr/hive/hive-1.2/hcatalog --hcatalog-table XXCSS_KTN_REQ_LINE_DETAIL --hcatalog-database frameworks_dataingestion
     * 
     */
    public static void runSqoop() {
        commands = new ArrayList<String>();
        commands.add("sqoop import -D mapred.child.java.opts=\'\\-Djava.security.egd=file:/dev/../dev/urandom\' --connect \'jdbc:oracle:thin:@(DESCRIPTION=(ADDRESS_LIST=(LOAD_BALANCE=ON)(FAILOVER=ON)(ADDRESS=(PROTOCOL=TCP)(HOST=173.37)(PORT=1541))(ADDRESS=(PROTOCOL=TCP)(HOST=173.37)(PORT=1541)))(CONNECT_DATA=(SERVICE_NAME=CAFI2PRD)(SERVER=DEDICATED)))\' --username XXCSS_O --password \"c*****3\" --split-by LINE_ITEM_ID -m 10 --query \"select LINE_ITEM_ID,LIST_PRICE,SERVICE_VALUE from XXCSS_KTN_REQ_LINE_DETAIL where \\$CONDITIONS AND lid_date > to_date(\'2016-10-13 00:00:00\',\'yyyy-MM-dd hh24:mi:ss\') and lid_date <= to_date(\'2016-10-13 03:04:18\',\'yyyy-MM-dd hh24:mi:ss\')\" --map-column-hive LINE_ITEM_ID=BIGINT,LIST_PRICE=BIGINT,SERVICE_VALUE=BIGINT --null-string '\\\\N' --null-non-string '\\\\N' --hcatalog-home /opt/mapr/hive/hive-1.2/hcatalog --hcatalog-table XXCSS_KTN_REQ_LINE_DETAIL --hcatalog-database frameworks_dataingestion");
        processBuilder = new ProcessBuilder(commands);
        try {
            System.out.println("Executing " + commands.toString());
            spawnProcess = processBuilder.start();
            BufferedReader reader = 
                    new BufferedReader(new InputStreamReader(spawnProcess.getErrorStream()));
            StringBuilder builder = new StringBuilder();
            String line = null;
            while ( (line = reader.readLine()) != null) {
               builder.append(line);
               builder.append(System.getProperty("line.separator"));
            }
            String result = builder.toString();
            System.out.println(result);
            try {
                exitValue = spawnProcess.waitFor();
                pid = getPID(spawnProcess);
                System.out.println("The PID is " + pid);
            } catch (InterruptedException e) {
                System.out.println(e.getMessage());
            } catch (Exception e) {
                System.out.println(e.getMessage());
            }
            System.out.println("Process exited with the status :" + exitValue);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /*
     * Retrieves the process id of the executed command.
     * 
     * @param process the executed process
     * 
     * @return PID
     */

    public static int getPID(Process process) {
        try {
            Class<?> processImplClass = process.getClass();
            Field fpid = processImplClass.getDeclaredField("pid");
            if (!fpid.isAccessible()) {
                fpid.setAccessible(true);
            }
            return fpid.getInt(process);
        } catch (Exception e) {
            System.out.println(e.getMessage());
            return -1;
        }
    }

    /*
     * Retrieves the current java process id
     * 
     * @return java process ID
     */

//  @SuppressWarnings("restriction")
//  public static int getCurrentJavaPID() {
//      int jvmpid = 0;
//      java.lang.management.RuntimeMXBean runtime = java.lang.management.ManagementFactory.getRuntimeMXBean();
//      try {
//          java.lang.reflect.Field jvm = runtime.getClass().getDeclaredField("jvm");
//          jvm.setAccessible(true);
//          sun.management.VMManagement mgmt = (sun.management.VMManagement) jvm.get(runtime);
//          java.lang.reflect.Method pid_method = mgmt.getClass().getDeclaredMethod("getProcessId");
//          pid_method.setAccessible(true);
//
//          jvmpid = (Integer) pid_method.invoke(mgmt);
//      } catch (Exception e) {
//          e.getMessage();
//      }
//      return jvmpid;
//  }

}

注意:出于安全考虑,我已使用虚拟变量替换了ip地址和密码。

尝试将命令作为字符串数组传递。但是,它不识别JDBC连接字符串

public static void runSqoop() {
        String[] commands = {"sqoop","import","-D mapred.child.java.opts=\'\\-Djava.security.egd=file:/dev/../dev/urandom\'","--connect", "\'jdbc:oracle:thin:@(DESCRIPTION=(ADDRESS_LIST=(LOAD_BALANCE=ON)(FAILOVER=ON)(ADDRESS=(PROTOCOL=TCP)(HOST=173.37)(PORT=1541))(ADDRESS=(PROTOCOL=TCP)(HOST=173.370)(PORT=1541)))(CONNECT_DATA=(SERVICE_NAME=CAFI2PRD)(SERVER=DEDICATED)))\'","--username","XXCSS_O","--password","\"c***3\"", "--split-by","LINE_ITEM_ID","-m","10","--query","\"select LINE_ITEM_ID,LIST_PRICE,SERVICE_VALUE from XXCSS_KTN_REQ_LINE_DETAIL where \\$CONDITIONS AND lid_date > to_date(\'2016-10-13 00:00:00\',\'yyyy-MM-dd hh24:mi:ss\') and lid_date <= to_date(\'2016-10-13 03:04:18\',\'yyyy-MM-dd hh24:mi:ss\')\"","--null-string","'\\\\N'","--null-non-string","'\\\\N'","--hcatalog-home","/opt/mapr/hive/hive-1.2/hcatalog","--hcatalog-table","XXCSS_KTN_REQ_LINE_DETAIL","--hcatalog-database","frameworks_dataingestion"};
        processBuilder = new ProcessBuilder(commands);
        try {
            System.out.println("Executing " + commands.toString());
            spawnProcess = processBuilder.start();
            BufferedReader reader = 
                    new BufferedReader(new InputStreamReader(spawnProcess.getErrorStream()));
            StringBuilder builder = new StringBuilder();
            String line = null;
            while ( (line = reader.readLine()) != null) {
               builder.append(line);
               builder.append(System.getProperty("line.separator"));
            }
            String result = builder.toString();
            System.out.println(result);
            try {
                exitValue = spawnProcess.waitFor();
                pid = getPID(spawnProcess);
                System.out.println("The PID is " + pid);
            } catch (InterruptedException e) {
                System.out.println(e.getMessage());
            } catch (Exception e) {
                System.out.println(e.getMessage());
            }
            System.out.println("Process exited with the status :" + exitValue);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

堆栈追踪:

  

cat:/ opt / mapr / zookeeper / zookeeperversion:没有这样的文件或目录   16/10/25 07:41:12 INFO sqoop.Sqoop:运行Sqoop版本:   1.4.6-mapr-1609 16/10/25 07:41:12 WARN tool.BaseSqoopTool:在命令行上设置密码是不安全的。考虑使用-P   代替。 16/10/25 07:41:13错误工具.BaseSqoopTool:收到错误   创建数据库管理器:java.io.IOException:没有连接管理器   串:   “JDBC:预言:瘦:@(DESCRIPTION =(ADDRESS_LIST =(LOAD_BALANCE = ON)(FAILOVER = ON)(ADDRESS =(PROTOCOL = TCP)(HOST = 173.37)(PORT = 1541))(ADDRESS =(PROTOCOL = TCP )(HOST = 173.37)(PORT = 1541)))(CONNECT_DATA =(SERVICE_NAME = CAFI2PRD)(SERVER = DEDICATED)))”           在org.apache.sqoop.ConnFactory.getManager(ConnFactory.java:191)           在org.apache.sqoop.tool.BaseSqoopTool.init(BaseSqoopTool.java:256)           在org.apache.sqoop.tool.ImportTool.init(ImportTool.java:89)           在org.apache.sqoop.tool.ImportTool.run(ImportTool.java:593)           在org.apache.sqoop.Sqoop.run(Sqoop.java:143)           在org.apache.hadoop.util.ToolRunner.run(ToolRunner.java:70)           在org.apache.sqoop.Sqoop.runSqoop(Sqoop.java:179)           在org.apache.sqoop.Sqoop.runTool(Sqoop.java:218)           在org.apache.sqoop.Sqoop.runTool(Sqoop.java:227)           在org.apache.sqoop.Sqoop.main(Sqoop.java:236)

1 个答案:

答案 0 :(得分:0)

您必须单独提供命令和参数,如下所示

  Process p = new ProcessBuilder("myCommand", "myArg").start();

OR

    ProcessBuilder pb =
       new ProcessBuilder("myCommand", "myArg1", "myArg2");
pb.start();

这是example