I premise that I don't know a lot about DataStage.
I just know that somebody else has created an "ETL job" and I need to launch it from my Java program, that acts as a client.
How should I do?
Edit:
The DataStage server is phisically different from the client where the Java program runs. I am not allowed running commans on the DataStage server. I need to connect via network. I imagined that DataStage provides some kind of network protocol, or webservice, or something so.
You can use the dsjob command - details see the Knowledge Center
Edit:
dsjob needs to be executed at the server.
You could use a insert into a database table from remote and trigger something (i.e. a UDF) that executes the dsjob on the server.
Alternatively use the WaitForFile stage and transfera file to the server.
I need that all server console output will appear in client output.
I'm invoking remote method on remote VM, during remote method execution i have some log4j report to the console (on remote).
I want to get/ return all log4j report to my client side console.
is this possible?
Not really. You have to understand that client and server only communicate through that RMI interface that you defined. Then both programs run in their own JVM; so stdout is something completely different for client and server. Same is of course true for any kind of logging infrastructure.
If you really want to push the server messages into your client logs; then you need to enhance that RMI interface, for example by allow the server to send back a List<String> that contains all the messages.
But please note: that is a rather bad design idea. You really do not want that your client logs contain server details. What happens on the server ... stays on the server. Your clients have no business knowing about such details. Because your users might find it very helpful when planning to attack your server ... to know what that thing is doing in detail!
Update: given your input, I would go for the following::
Make sure that you can really capture any char printed to stdout/stderr on your server; for example by "replacing" stdout/stderr so that anything printed there goes in some file (see here). Alternatively, if your VM is Linux, you can make sure both get piped into files.
Instead of trying to capture stuff within your RMI service, I would go for a simpler solution - by adding a RMI interface that allows you to pull those stdout/stderr files from your server. In other words: keep your current RMI calls as they are; but built another service that you can use to retrieve full log files at arbitrary points in time.
I know Java can act as a client for reading/writing named pipes, but I need another program which acts as a server.
In this case the program I am communicating with must act as the client, rather than the server. Is it possible for Java to act in server mode for named pipes?
EDIT: In named pipes (Windows) there are client and server modes. A server must first be established before a client can connect to it. I have a legacy application which acts as a 'client', this means that it connects to what it assumes is an already established named pipe.
I have a new java application which I would like to have communicate with this legacy app using named pipes. I have only found examples of how to use Java named pipes in connection to previously established named pipes.
Well on linux and mac you can always have java emit to the console one line at a time. Example:
In one terminal window to this:
mkfifo myPipe
java -jar mydataserver.jar > mkfifo
In a second terminal window do this:
while read line; do echo "What has been passed through the pipe is \
${line}"; done<myPipe
Yes, you can create named pipe on the Java server using JNA library https://github.com/java-native-access/jna
It is clearly shown in the following test: https://github.com/java-native-access/jna/blob/master/contrib/platform/test/com/sun/jna/platform/win32/Kernel32NamedPipeTest.java
API of JNA wrapper is the same as Win32 hence you will be able to use all the features and power of named pipes on Windows.
I have two servers, one that runs my program written in Java (Server A) and one that stores a graph (Server B) that must be continuously accessed by Server A. To access Server B you must ssh with a username and password using Server B's IP address.
As of now I have failed to find a method to continuously access a directory on a different server and I am wondering if anyone knows a method that lets me do this (or if it is not possible, if there is a workaround).
I have looked into SSH libraries, but they all seem to only give you access to the directory for a brief amount of time. I need continuos access because I write and read from the graph on Server B all the time.
I basically want to make a proxy directory on Server A that actually refers/links to the directory on Server B:
graphDb = new EmbeddedGraphDatabase("/192.168.1.**/media/graphDB");
Any help would be great.
Probably unrelated option:
If client and server are Linux machines, you can use rsync to synchronize files between them. In that way you have a copy of the files on server A. The rsync command could be executed from the Java program or periodically from a cronjob on server A.
You could write your own client/server service, so that the server service provide you with the means to send data over the network to. It tends to be a lot of work though.
You could write your self a "heart beat" service on the client that tests the SSH connection and reestablishes it if it closes
You could "test" the ssh connection before you writing/reading from the connection
You could do as AlperAkture suggests (and mount the directory as a remote drive)
We have some applications that sometimes get into a bad state, but only in production (of course!). While taking a heap dump can help to gather state information, it's often easier to use a remote debugger. Setting this up is easy -- one need only add this to his command line:
-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=PORT
There seems to be no available security mechanism, so turning on debugging in production would effectively allow arbitrary code execution (via hotswap).
We have a mix of 1.4.2 and 1.5 Sun JVMs running on Solaris 9 and Linux (Redhat Enterprise 4). How can we enable secure debugging? Any other ways to achieve our goal of production server inspection?
Update: For JDK 1.5+ JVMs, one can specify an interface and port to which the debugger should bind. So, KarlP's suggestion of binding to loopback and just using a SSH tunnel to a local developer box should work given SSH is set up properly on the servers.
However, it seems that JDK1.4x does not allow an interface to be specified for the debug port. So, we can either block access to the debug port somewhere in the network or do some system-specific blocking in the OS itself (IPChains as Jared suggested, etc.)?
Update #2: This is a hack that will let us limit our risk, even on 1.4.2 JVMs:
Command line params:
-Xdebug
-Xrunjdwp:
transport=dt_socket,
server=y,
suspend=n,
address=9001,
onthrow=com.whatever.TurnOnDebuggerException,
launch=nothing
Java Code to turn on debugger:
try {
throw new TurnOnDebuggerException();
} catch (TurnOnDebugger td) {
//Nothing
}
TurnOnDebuggerException can be any exception guaranteed not to be thrown anywhere else.
I tested this on a Windows box to prove that (1) the debugger port does not receive connections initially, and (2) throwing the TurnOnDebugger exception as shown above causes the debugger to come alive. The launch parameter was required (at least on JDK1.4.2), but a garbage value was handled gracefully by the JVM.
We're planning on making a small servlet that, behind appropriate security, can allow us to turn on the debugger. Of course, one can't turn it off afterward, and the debugger still listens promiscuously once its on. But, these are limitations we're willing to accept as debugging of a production system will always result in a restart afterward.
Update #3: I ended up writing three classes: (1) TurnOnDebuggerException, a plain 'ol Java exception, (2) DebuggerPoller, a background thread the checks for the existence of a specified file on the filesystem, and (3) DebuggerMainWrapper, a class that kicks off the polling thread and then reflectively calls the main method of another specified class.
This is how its used:
Replace your "main" class with DebuggerMainWrapper in your start-up scripts
Add two system (-D) params, one specifying the real main class, and the other specifying a file on the filesystem.
Configure the debugger on the command line with the onthrow=com.whatever.TurnOnDebuggerException part added
Add a jar with the three classes mentioned above to the classpath.
Now, when you start up your JVM everything is the same except that a background poller thread is started. Presuming that the file (ours is called TurnOnDebugger) doesn't initially exist, the poller checks for it every N seconds. When the poller first notices it, it throws and immediately catches the TurnOnDebuggerException. Then, the agent is kicked off.
You can't turn it back off, and the machine is not terribly secure when its on. On the upside, I don't think the debugger allows for multiple simultaneous connections, so maintaining a debugging connection is your best defense. We chose the file notification method because it allowed us to piggyback off of our existing Unix authen/author by specifying the trigger file in a directory where only the proper uses have rights. You could easily build a little war file that achieved the same purpose via a socket connection. Of course, since we can't turn off the debugger, we'll only use it to gather data before killing off a sick application. If anyone wants this code, please let me know. However, it will only take you a few minutes to throw it together yourself.
If you use SSH you can allow tunneling and tunnel a port to your local host. No development required, all done using sshd, ssh and/or putty.
The debug socket on your java server can be set up on the local interface 127.0.0.1.
You're absolutely right: the Java Debugging API is inherently insecure. You can, however, limit it to UNIX domain sockets, and write a proxy with SSL/SSH to let you have authenticated and encrypted external connections that are then proxied into the UNIX domain socket. That at least reduces your exposure to someone who can get a process into the server, or someone who can crack your SSL.
Export information/services into JMX and then use RMI+SSL to access it remotely. Your situation is what JMX is designed for (the M stands for Management).
Good question.
I'm not aware of any built-in ability to encrypt connections to the debugging port.
There may be a much better/easier solution, but I would do the following:
Put the production machine behind a firewall that blocks access to the debugging port(s).
Run a proxy process on the host itself that connects to the port, and encrypts the input and output from the socket.
Run a proxy client on the debugging workstation that also encrypts/decrypts the input. Have this connect to the server proxy. Communication between them would be encrypted.
Connect your debugger to the proxy client.