I'm trying to write a simple Java program to inject an MQ message onto a queue. I'm very inexperienced with writing to MQ queues using Java and have a couple of questions.
Can I connect to the unix queue on the unix box from my windows machine?
When I try to run the application I get a ....
java.lang.UnsatisfiedLinkError: no mqjbnd05 in java.library.path
From the sounds of what I could find in google I am missing some sort of resource. I'm thinking I'm getting this error possibly bc I'm not allowed to connect to the queue from windows?
Any good examples of how to achieve what I'm doing or help would be appreciated.
public class MQInject {
private MQQueueManager _queueManager = null;
private Hashtable params = null;
public int port = 1414;
public static final String hostname = "UQMYPOSIS1";
public static final String channel = "MQTX1012.MQTX1013";
public static final String qManager = "MQTX1013";
public static final String outputQName = "IIS.TLOG.5";
public MQInject(){
super();
}
public void init(){
//Set MQ connection credentials to MQ Envorinment.
MQEnvironment.hostname = hostname;
MQEnvironment.channel = channel;
MQEnvironment.port = port;
//MQEnvironment.userID = "";
//QEnvironment.password = password;
//set transport properties.
MQEnvironment.properties.put(MQC.TRANSPORT_PROPERTY, MQC.TRANSPORT_MQSERIES_CLIENT);
try {
//initialize MQ manager.
_queueManager = new MQQueueManager(qManager);
} catch (MQException e) {
e.printStackTrace();
}
}
public static void main(String[] args)
{
MQInject write = new MQInject();
try
{
write.selectQMgr();
write.write();
}
catch (IllegalArgumentException e)
{
System.out.println("Usage: java MQWrite <-h host> <-p port> <-c channel> <-m QueueManagerName> <-q QueueName>");
System.exit(1);
}
catch (MQException e)
{
System.out.println(e);
System.exit(1);
}
}
private void selectQMgr() throws MQException
{
_queueManager = new MQQueueManager(qManager);
}
private void write() throws MQException{
String line;
int lineNum=0;
int openOptions = MQC.MQOO_OUTPUT + MQC.MQOO_FAIL_IF_QUIESCING;
try {
MQQueue queue = _queueManager.accessQueue( outputQName,
openOptions,
null, // default q manager
null, // no dynamic q name
null ); // no alternate user id
DataInputStream input = new DataInputStream(System.in);
System.out.println("MQWrite v1.0 connected");
System.out.println("and ready for input, terminate with ^Z\n\n");
// Define a simple MQ message, and write some text in UTF format..
MQMessage sendmsg = new MQMessage();
sendmsg.format = MQC.MQFMT_STRING;
sendmsg.feedback = MQC.MQFB_NONE;
sendmsg.messageType = MQC.MQMT_DATAGRAM;
sendmsg.replyToQueueName = "ROGER.QUEUE";
sendmsg.replyToQueueManagerName = qManager;
MQPutMessageOptions pmo = new MQPutMessageOptions(); // accept the defaults, same
// as MQPMO_DEFAULT constant
while ((line = input.readLine()) != null){
sendmsg.clearMessage();
sendmsg.messageId = MQC.MQMI_NONE;
sendmsg.correlationId = MQC.MQCI_NONE;
sendmsg.writeString(line);
// put the message on the queue
queue.put(sendmsg, pmo);
System.out.println(++lineNum + ": " + line);
}
queue.close();
_queueManager.disconnect();
}catch (com.ibm.mq.MQException mqex){
System.out.println(mqex);
}
catch (java.io.IOException ioex){
System.out.println("An MQ IO error occurred : " + ioex);
}
}
}
For your first question, yes you can have a queue manager running on a UNIX host which is accessed by a client running on a Windows host.
For your second question, the mqjbnd05 library is only used to connect to the queue manager in binding mode (i.e. when the queue manager and the program accessing the queues are on the same host) and is not part of the MQ client installation. See http://www-01.ibm.com/support/docview.wss?uid=swg21158430 for more details. Looking through your code I can see that the init() function is specifying MQC.TRANSPORT_MQSERIES_CLIENT although I cannot see that the init() function is being called. Also it might be worth checking whether mqjbnd05 is specified in the library path and if so removing it.
Whilst probably not related to the error your getting, one other thing that might be worth checking is that the channel MQTX1012.MQTX1013 is a server connection channel as opposed to a sender or receiver channel.
Related
I am implementing an FTP server in Java for a project. I can start the server but when I try to connect with a client it is stuck on "waiting for welcome message". I've looked at several examples but I'm not sure where I'm going wrong. Here is the class I have. I will eventually break some of this out into other methods.
The user parameters have been cleared for the purposes of this post.
public class FTPServer {
final int PORT = 2221;
String userfile = "";
String username="";
String password = ""
String homedir ="";
private FtpServer server=null;
public FTPServer() {}
public FTPServer(final String ipaddress, final int port){
FtpServerFactory serverFactory = new FtpServerFactory();
ListenerFactory listenerfactory = new ListenerFactory();
listenerfactory.setDataConnectionConfiguration(
new DataConnectionConfigurationFactory().createDataConnectionConfiguration());
ConnectionConfigFactory connection = new ConnectionConfigFactory();
connection.setMaxLoginFailures(10);
connection.setLoginFailureDelay(5);
connection.setAnonymousLoginEnabled(false);
// set the ip address of the listener
listenerfactory.setServerAddress(ipaddress);
// set the port of the listener
if (port == 0)
{ listenerfactory.setPort(PORT);}
else {listenerfactory.setPort(port);
// replace the default listener
serverFactory.addListener("default", listenerfactory.createListener());
serverFactory.setConnectionConfig(connection.createConnectionConfig());
}
PropertiesUserManagerFactory userManagerFactory = new PropertiesUserManagerFactory();
userManagerFactory.setFile(new File(userfile));
userManagerFactory.setPasswordEncryptor(new SaltedPasswordEncryptor());
UserManager um = userManagerFactory.createUserManager();
BaseUser user = new BaseUser();
user.setName(username);
user.setPassword(password);
user.setHomeDirectory(homedir);
try {
um.save(user);
} catch (FtpException e1) {
// TODO Auto-generated catch block
this.StopServer();
e1.printStackTrace();
}
serverFactory.setUserManager(um);
server = serverFactory.createServer();
}
public void StopServer(){ this.server.stop(); }
public void StartServer()
{
try {
server.start();
} catch (FtpException e) {
// handle this eventually, good enough for testing now
e.printStackTrace();
}
}
Here is the code that creates the server and starts and stops it
final int port = 0;
final String ipaddress = "";
FTPServer server = new FTPServer(ipaddress,port);
server.StartServer();
server.StopServer();
I'd say that FtpServer.Start only starts listening on the incoming port. It does not block. You kill the server immediately afterwards by calling .Stop.
You have to wait in your code explicitly to keep the server running.
server.StartServer();
Thread.sleep(Long.MAX_VALUE);
We are deploying a Java project on Linux Server. A file is generated by the project which is then sent to a remote server.
It was earlier implemented using Jsch. However, due to its dependency on JCE and the inability to upgrade the java version (from 5) we are switching to Ganymed. I am using Ganymed build 210 (viz. is tested for java 5; http://www.ganymed.ethz.ch/ssh2)
This is the function I am using to sftp the file.
public boolean sftp_put() {
File privateKeyFile = new File(identityPath);
File rfile = new File(hostDir);
File lfile = new File(lpath);
boolean success = false;
try {
if (!lfile.exists() || lfile.isDirectory()) {
throw new IOException("Local file must be a regular file: "
+ lpath);
}
Connection ssh = new Connection(host, port);
ssh.connect();
ssh.authenticateWithPublicKey(user, privateKeyFile, password);
SFTPv3Client sftp = new SFTPv3Client(ssh);
try {
SFTPv3FileAttributes attr = sftp.lstat(hostDir);
if (attr.isDirectory()) {
rfile = new File(hostDir, lfile.getName());
}
} catch (SFTPException e) {
try {
SFTPv3FileAttributes attr = sftp.lstat(rfile.getParent());
if (!attr.isDirectory()) {
throw new IOException(
"Remote file's parent must be a directory: "
+ hostDir + "," + e);
}
} catch (SFTPException ex) {
throw new IOException(
"Remote file's parent directory must exist: "
+ hostDir + "," + ex);
}
}
SFTPv3FileHandle file = sftp.createFileTruncate(rfile
.getCanonicalPath());
long fileOffset = 0;
byte[] src = new byte[32768];
int i = 0;
FileInputStream input = new FileInputStream(lfile);
while ((i = input.read(src)) != -1) {
sftp.write(file, fileOffset, src, 0, i);
fileOffset += i;
}
input.close();
sftp.closeFile(file);
sftp.close();
success=true;
} catch (IOException e1) {
logger.warn("Exception while trying to sftp", e)
}
return success;
}
I am unable to connect to the remote server possibly due to binding issues and unsure on how to proceed? I am thinking on binding a local address before the SFTP.
So I wrote a socket function.
public Socket createSocket(String destinationHost, int destinationPort)
throws IOException, UnknownHostException {
logger.info("sftp configured bind address : " + bindAddress
+ ", bind port : " + bindPort);
Socket socket = new Socket();
socket.bind(new InetSocketAddress(bindAddress, bindPort));
socket.connect(new InetSocketAddress(destinationHost, destinationPort),
connectionTimeOut);
if (socket.isBound()) {
logger.info("sftp actual bind port : " + socket.getLocalPort());
} else {
logger.warn("sftp socket not bound to local port");
}
return socket;
}
However this is also not working, and I am getting a Socket Exception.
EDIT: So I was creating the socket in the right way but no where am I using the same socket for creating the connection. Such a method is not defined in any of the Ganymed libraries.
Since there was not an inherent method in ganymed, I edited the source code to write a method.
Following are the edits I made.
to the class where I am using
SocketAddress sourceAddress = new InetSocketAddress(bindAddress,
bindPort);
Connection ssh = new Connection(host, port);
ssh.bindSourceAddress(sourceAddress);
ssh.connect();
then I made some changes to connection.class of Ganymed API. Imported class and declared variables accordingly
This is the simple method for passing the bindAddress.
public void bindSourceAddress(SocketAddress sourceAddress) {
this.sourceAddress = sourceAddress;
}
Passing the address to Transport Manager class when initialize method is used.
if (sourceAddress != null) {
tm.initialize(cryptoWishList, verifier, dhgexpara,
connectTimeout, getOrCreateSecureRND(), proxyData,
sourceAddress);
} else {
tm.initialize(cryptoWishList, verifier, dhgexpara,
connectTimeout, getOrCreateSecureRND(), proxyData);
}
Modified the constructor of initialize method. It in turn calls an establish connection function, which is similarly modified to accomodate SocketAddress.
private void establishConnection(ProxyData proxyData, int connectTimeout, SocketAddress sourceAddress) throws IOException
{
/* See the comment for createInetAddress() */
if (proxyData == null)
{
InetAddress addr = createInetAddress(hostname);
//test
if (sourceAddress != null) {
sock.bind(sourceAddress);
}
sock.connect(new InetSocketAddress(addr, port), connectTimeout);
sock.setSoTimeout(0);
return;
}
if (proxyData instanceof HTTPProxyData)
{
HTTPProxyData pd = (HTTPProxyData) proxyData;
/* At the moment, we only support HTTP proxies */
InetAddress addr = createInetAddress(pd.proxyHost);
//test
if (sourceAddress != null) {
sock.bind(sourceAddress);
}
sock.connect(new InetSocketAddress(addr, pd.proxyPort), connectTimeout);
sock.setSoTimeout(0);
Finally bound the socket. Being a java Novice it took me my own sweet time to get this right. No one will most probably read this or need it, but posted this solution just in case for someone like me!
I'm writing a Thrift application that can take input from an outside website and process it. However, the program is hanging at the line:
TTransport transport = new THttpClient("this.host.com");
And I'm not sure why it's happening. It's not giving me any error messages and such but it also doesn't progress forward. It just hangs when I receive a request from a client that calls buildModel(). Here's my code:
private void buildModel() throws UnknownHostException {
// Map of user preferences by Mahout user id
FastByIDMap<Collection<Preference>> userIDPrefMap = new FastByIDMap<Collection<Preference>>();
System.out.println("Building model");
try {
TTransport transport = new THttpClient(this.host);
TProtocol protocol = new TBinaryProtocol(transport);
MyCustomDatabase.Client client = new MyCustomDatabase.Client(protocol);
ConnectionParams con_params = new ConnectionParams();
con_params.setUser(this.username);
con_params.setPassword(this.password);
Connection con = client.open_connection(con_params);
ResultSet res = client.execute_sql(con, "select * from " + this.database + "." + this.tableName, null);
for (Tuple t : res.getTuples()) {
List<ByteBuffer> cells = t.getCells();
int userID = Integer.parseInt(new String(cells.get(0).array()));
int itemID = Integer.parseInt(new String(cells.get(1).array()));
int ratingValue = Integer.parseInt(new String(cells.get(2).array()));
Collection<Preference> userPrefs = userIDPrefMap.get(userID);
if (userPrefs == null) {
userPrefs = Lists.newArrayListWithCapacity(2);
userIDPrefMap.put(userID, userPrefs);
}
userPrefs.add(new GenericPreference(userID, itemID, ratingValue));
}
} catch(Exception e) {
e.printStackTrace();
}
this.delegate = new GenericDataModel(GenericDataModel.toDataMap(userIDPrefMap, true));
}
Any help greatly appreciated!
Its hard to tell exactly what the issue is but some things to note:
1) new THttpClient(this.host) should take a URI string not a host name. In the Thrift Java library this is the constructor that you are calling:
public THttpClient(String url) throws TTransportException {
try {
url_ = new URL(url);
this.client = null;
this.host = null;
} catch (IOException iox) {
throw new TTransportException(iox);
}
}
If you are just passing a host name instead of a URI you probably won't get the results you expect.
2) In the javadoc for the THttpClient class they suggest using the Apache HttpClient constructor instead of the default HttpURLConnection one anyhow, both for better performance and to avoid exhausting the open file descriptor limit under heavy load.
I would suggest that try passing a valid URI to the constructor, and if that does not work try using HttpClient instead, or use both of those measures.
Please help an MQ nubee to write his first Java Client, I got a little bit lost in the Oracle docs.
I have OpenMQ up and running.
In the OpenMQ Administration Console I established a broker named "MyFirstTest"
1 of 6 services is "jms" (which seems to be the most easy to use service), this service is up and running, too (saying: Service state running).
So I come to the interesting part.
How do I connect to the broker "MyFirstTest", then to send a message in, and last but least read this message perhaps from a second client.
I think I have to find the already existing queue instead of using
new com.sun.messaging.Queue
Any example or link to is appreciated.
public class HelloWorldMessage {
public static void main(String[] args) {
try {
ConnectionFactory myConnFactory;
Queue myQueue;
myConnFactory = new com.sun.messaging.ConnectionFactory();
Connection myConn = myConnFactory.createConnection();
Session mySess = myConn.createSession(false, Session.AUTO_ACKNOWLEDGE);
myQueue = new com.sun.messaging.Queue("MyFirstTest");
//Create a message producer.
MessageProducer myMsgProducer = mySess.createProducer(myQueue);
//Create and send a message to the queue.
TextMessage myTextMsg = mySess.createTextMessage();
myTextMsg.setText("Hello World");
System.out.println("Sending Message: " + myTextMsg.getText());
myMsgProducer.send(myTextMsg);
//Create a message consumer.
MessageConsumer myMsgConsumer = mySess.createConsumer(myQueue);
//Start the Connection created in step 3.
myConn.start();
//Receive a message from the queue.
Message msg = myMsgConsumer.receive();
//Retreive the contents of the message.
if (msg instanceof TextMessage) {
TextMessage txtMsg = (TextMessage) msg;
System.out.println("Read Message: " + txtMsg.getText());
}
//Close the session and connection resources.
mySess.close();
myConn.close();
} catch (Exception jmse) {
System.out.println("Exception occurred : " + jmse.toString());
jmse.printStackTrace();
}
}
}
//Assuming server supports multiple clients, your client can look like this:
//Ref: http://docs.oracle.com/javase/tutorial/networking/sockets/readingWriting.html
//untested code
class client{
.....
....
private static Socket echoSocket;
//main can be in another class also
public static void main(.... args[]){
client nodeI,nodeII;
nodeI = new client("speaker/sender");
nodeII = new client("listener/recvr");
nodeI.connect2Server();
nodeI.sendMssgInstr2Server(node);
}
public void connect2Server(){
try {
echoSocket = new Socket("<jms.srvr.ip>", <port#>);
} catch (UnknownHostException e) {
System.err.println("Don't know about host: <jms.srvr.ip>.");
System.exit(1);
}
}
public void sendMssgInstr2Server throws IOException (client RecipientClientNodeII){
out = new PrintWriter(echoSocket.getOutputStream(), true);
out.println("sending message:"+mssgQueue.poll() + " =>recipient client is now reading:"+RecipientClientNodeII.receive);
}
public void receive(){
try{
in = new BufferedReader(new InputStreamReader(echoSocket.getInputStream()));
}catch (IOException e) {
System.err.println("Couldn't get I/O for "+"the connection to: <jms.srvr.ip>.");
System.exit(1);
}
while(1)
in.readLine();
}
//other methods
.......
.......
}; //class client ends
i've a java servlet that makes some reports. When a user choose a report it makes a query on a db and stream the xls report to the client. All in synchronous way. The problem is that sometimes i've a lot of records to fetch from the db and i would like to give a better user experience, allowing the user to do something else while the report is processing and popping out in some way the link when the process is finished. Is there a java library or some techniques to avoid the long waiting and achieve that goal?
Right now i've prepared a piece of code that in a asynchronous way completes the report and sends an email to the registered client, with the url from wich download the file, but it has to be replaced with something else because i can no longer communicate by email.
Thanks in advance
heres my take on this, i dont know of a single library that will exactly match you needs, youd probably need some custom development here.
I believe you have implemented async service that on completion sends
out an email for notification. Instead of sending out an email, let
that thread update a job table of some sort -- an entry in a db table
or some application/session scoped map.
Have a servlet/restful ws
expose that job table at some url. Poll the url at regular
intervals. Ajax poll is a standard feature in js libraries JQuery,
Prototype.
When you get a response that some report is complete, show
some popup or may be a facebook you-have-notification kind of thing
on the client side.
i have not considered authentication/authorization issues here, you need to take care of that as well.
Hope this helps
A multithreaded client server program to download my image files.
Since there are four files to download the client makes 4 connection attempts. This is not limited to 4 but the files sent by the FileServer will get repeated after the fourth attempt. The save dialog and file saving is done in different threads so as to not hamper the file downloading.
Here is the FileServer...
public class FileServer {
private final ExecutorService exec = Executors.newCachedThreadPool();
final String[] fileNames = {
"C:\\Users\\clobo\\Pictures\\Arpeggios\\Ex 1.jpg",
"C:\\Users\\clobo\\Pictures\\Arpeggios\\Ex 2.jpg",
"C:\\Users\\clobo\\Pictures\\Arpeggios\\Ex 3.jpg",
"C:\\Users\\clobo\\Pictures\\Arpeggios\\Ex 4.jpg"
};
public void start() throws IOException {
ServerSocket socket = new ServerSocket(7777);
System.out.println("Waiting for client message...");
while (!exec.isShutdown()) {
try {
for (final String fileName : fileNames){
final Socket conn = socket.accept();
exec.execute(new Runnable() {
public void run() {
sendFile(conn,fileName);
}
});
}
} catch (RejectedExecutionException e) {
if (!exec.isShutdown())
log("task submission rejected", e);
}
}
}
public void stop() {
System.out.println("Shutting down server...");
exec.shutdown();
}
private void log(String msg, Exception e) {
Logger.getAnonymousLogger().log(Level.WARNING, msg, e);
}
public void sendFile(Socket conn, String fileName) {
File myFile = new File(fileName);
if (!myFile.exists()) {
log("File does not exist!",null);
}
// file does exist
System.out.println(Thread.currentThread().getName());
System.out.println("AbsolutePath:" + myFile.getAbsolutePath());
System.out.println("length: " + myFile.length());
if (myFile.exists()) {
try {
ObjectOutputStream oos = new ObjectOutputStream(
conn.getOutputStream());
oos.writeObject(myFile);
oos.close();
} catch (IOException e) {
log("IOException Error", e);
e.printStackTrace();
}
}
}
public static void main(String[] args) throws IOException {
FileServer fs = new FileServer();
fs.start();
}
}
here is the FileServerClient...
public class FileServerClient {
private final ExecutorService exec = Executors.newCachedThreadPool();
Frame myFrame = new Frame();
List<File> fileList = new ArrayList<File>();
public void receiveFileFromServer() throws Exception{
Socket sock = null;
InputStream socketInputStream = null;
String host = "localhost";
int port = 7777;
for (int i=0;i<4;i++) {
sock = new Socket(host, port);
socketInputStream = sock.getInputStream();
System.out.println("Connection successful...");
// recieve the file
ObjectInputStream ois = new ObjectInputStream(socketInputStream);
// file from server is deserialized
final File myfile = (File) ois.readObject();
fileList.add(myfile);
// deserialized file properties
System.out.println("AbsolutePath: " + myfile.getAbsolutePath());
System.out.println("FileName:" + myfile.getName());
System.out.println("length" + myfile.length());
exec.execute(new Runnable() {
public void run() {
saveFile(myfile);
}
});
}
}
private void saveFile(File myfile) {
FileDialog fileDialog = new FileDialog(myFrame,
"Choose Destination for "+ myfile.getName(), FileDialog.SAVE);
fileDialog.setDirectory(null);
fileDialog.setFile("enter file name here");
fileDialog.setVisible(true);
String targetFileName = fileDialog.getDirectory()
+ fileDialog.getFile() + ".jpg";
System.out.println("File will be saved to: " + targetFileName);
copyBytes(myfile, targetFileName);
}
private void copyBytes(File originalFile, String targetFileName) {
try {
FileInputStream in = new FileInputStream(originalFile);
FileOutputStream out = new FileOutputStream(targetFileName);
int c;
while ((c = in.read()) != -1) {
out.write(c);
}
out.close();
in.close();
} catch (Exception e) {
log("IOException Error", e);
}
}
private void log(String msg, Exception e) {
Logger.getAnonymousLogger().log(Level.WARNING, msg, e);
}
public static void main(String[] args) throws Exception {
FileServerClient client = new FileServerClient();
client.receiveFileFromServer();
}
}
You could make an asynchronous request from the client. Lets assume that you client is an html page. When the user selects a report and clicks on 'submit' you could fire an ajax request with the report parameters (jquery can be useful for this). It would be good to keep a section on the user homepage that says something like 'prepared reports'. The client can then goto the prepared report section to download the report. As specified in the comments above, you may also have to implement a popup that informs the user that the requested report is ready. the popup is shown when the ajax requests returns successfully. However, the client may have logged out by the time the report finishes, so it may be a good idea to make the download link available again in the 'prepared reports' section when the user logs in.