Search code examples
javasshweblogicjschwlst

Invoke WLST commands with JSch


I'm trying to run a restart server command on WLST through a remote Java web app.

This is what I'm trying to execute:

StringBuilder sb = new StringBuilder();
sb.append("/u01/app/oracle/jdk1.8.0_65/bin/./java -cp /u01/app/oracle/product/Oracle_Home/wlserver/server/lib/weblogic.jar weblogic.WLST");
sb.append(";connect(\'weblogic\',\'" + consolePass + "\',\'" + fullAddress + "\')");
sb.append(";domainRuntime()");
sb.append(";cd(\'/ServerLifeCycleRuntimes/" + serverName + "\')");
sb.append(";cmo.shutdown())");
sb.append(";start(" + serverName + ",'Server')");
String command = sb.toString();

JSch jsch = new JSch();
Session session = jsch.getSession(user, host, port);
session.setUserInfo(new OracleUserInfo(pass));
session.connect();

Channel channel = session.openChannel("exec");
((ChannelExec) channel).setCommand(command);
channel.setInputStream(null);
((ChannelExec) channel).setErrStream(System.err);
InputStream in = channel.getInputStream();
channel.connect();

byte[] tmp = new byte[1024];
while (true) {
    while (in.available() > 0) {
        int i = in.read(tmp, 0, 1024);
        if (i < 0)
            break;
        System.out.print(new String(tmp, 0, i));
    }
    if (channel.isClosed()) {
        if (in.available() > 0)
            continue;
        System.out.println("exit-status: " + channel.getExitStatus());
        break;
    }
    try {
        Thread.sleep(1000);
    } catch (Exception ee) {
    }
}
channel.disconnect();
session.disconnect();

I'm using ';' to separate the commands, since I thought it was required to run multiple commands.

Unfortunately, it gives a syntax error on line 2.

bash: -c: line 0: syntax error near unexpected token 'weblogic','password','t3://host:7001''
bash: -c: line 0:
/u01/app/oracle/jdk1.8.0_65/bin/./java -cp /u01/app/oracle/product/Oracle_Home/wlserver/server/lib/weblogic.jar weblogic.WLST;connect('weblogic','password','t3://host:7001')'

I tried to add \n after the first line, and the result was that the first line was executed (so it entered WLST), but none of the remaining commands were.

StringBuilder sb = new StringBuilder();
sb.append("/u01/app/oracle/jdk1.8.0_65/bin/./java -cp /u01/app/oracle/product/Oracle_Home/wlserver/server/lib/weblogic.jar weblogic.WLST\n");
sb.append(";connect(\'weblogic\',\'" + consolePass + "\',\'" + fullAddress + "\')\n");
sb.append(";domainRuntime()\n");
sb.append(";cd(\'/ServerLifeCycleRuntimes/" + serverName + "\')\n");
sb.append(";cmo.shutdown())\n");
String command = sb.toString();

Result:

Initializing WebLogic Scripting Tool (WLST) ...
Welcome to WebLogic Server Administration Scripting Shell
Type help() for help on available commands
wls:/offline>

I tested the command manually and it worked. The problem seems to be with JSch with WLST interface, since it opens another shell interface.

Any ideas how I could run WLST commands with JSch?

PS1: I know my JSch code works because I have a feature on the same app to deploy. Basically, it runs a jscp to upload the war, and then ssh to execute the weblogic.Deployer -deploy command.

PS2: I do have a .py script to do that, but as of now, it must be on the server to be executed. I'm thinking about doing an jscp to a temp folder, run the script and then delete. But I'm curious to find out how to run multiple commands on WLST with JSch.

Thanks in advance.

UPDATE

Code working (Thanks Martin)

    Channel channel = session.openChannel("exec");
    ((ChannelExec) channel).setCommand(command);

    InputStream in = channel.getInputStream();
    OutputStream out = channel.getOutputStream();
    ((ChannelExec) channel).setErrStream(System.err);
    channel.connect();
    for (String wlstCommand : wlstCommands) {
        out.write((wlstCommand).getBytes());
    }
    out.flush();

Solution

  • The ; can indeed by used in *nix based system to execute multiple commands in one shell command-line.

    But what you are executing are not shell commands. Those are WLST commands, right? So you have to feed them to WLST.

    Like this:

    Channel channel = session.openChannel("exec");
    ((ChannelExec) channel).setCommand("java -cp /.../weblogic.jar weblogic.WLST");
    OutputStream out = channel.getOutputStream();
    channel.connect();
    out.write(("connect('weblogic'...)\n").getBytes());
    out.write(("domainRuntime()\n").getBytes());
    ...
    

    It's basically the same as generic Providing input/subcommands to command executed over SSH with JSch.