MQ Pure Java Client Lib - java

I am evaluating Websphere MQ7. I am a traditionally a TibRV guy. One thing I do not like is the fact that the IBM java client libs require C++ libs in order to run. Is there anyway to run the IBM java client libs without requiring the C++ libs? e.g. is there a pure java client library for MQ ?

I have previously written a JMS client to MQSeries v6 (not your version, I know) without needing to install native libs. The only IBM libraries I required were titled:
com.ibm.mq-6.jar
com.ibm.mqbind.jar
com.ibm.mqjms-6.jar
According to this post they come with the client install. I assume you can install it once, then re-use the jars (any licensing issues and expert opinions aside).
EDIT: In response to your comment, here's the client code I hacked up. It is for reading messages from a queue and blatting them to files. It's written in Scala. I hope it helps somewhat.
import com.ibm.mq._
import java.text._
import java.io._
case class QueueDetails(hostname: String, channel: String,
port: Int, queueManager: String, queue: String)
class Reader(details: QueueDetails) {
def read = {
MQEnvironment.hostname = details.hostname
MQEnvironment.channel = details.channel
MQEnvironment.port = details.port
val props = new java.util.Hashtable[String, String]
props.put(MQC.TRANSPORT_PROPERTY, MQC.TRANSPORT_MQSERIES)
MQEnvironment.properties = props
val qm = new MQQueueManager(details.queueManager)
val options = MQC.MQOO_INPUT_AS_Q_DEF | MQC.MQOO_INQUIRE
val q = qm.accessQueue(details.queue, options, null, null, null)
val depth = q.getCurrentDepth
val indexFormat = new DecimalFormat(depth.toString.replaceAll(".", "0"))
def exportMessage(index: Int): Unit = {
if (index < depth) {
val msg = new MQMessage
q.get(msg, new MQGetMessageOptions)
val msgLength = msg.getMessageLength
val text = msg.readStringOfByteLength(msgLength)
val file = new File("message_%s.txt".format(indexFormat.format(index)))
val writer = new BufferedWriter(new FileWriter(file))
writer.write(text)
writer.close
println(file.getAbsolutePath)
exportMessage(index + 1)
}
}
exportMessage(0)
q.close
qm.disconnect
}
}

Related

Jar file gets corrupted when sent over socket in Scala

I'm aware that Scala uses Java sockets, but I don't quite understand the answers from questions that people have had with the same problem but strictly in Java.
Here is my code:
I am trying to send a jar file through a socket, but when I try to open the jar file from the other side, the file seems to be corrupted. How can I fix this?
Server:
object server extends App {
import java.net._
import java.io._
import scala.io._
import scala.io.Source
val server = new ServerSocket(9999)
//Master should ping the slave actor to request for jar file
while (true) {
val s = server.accept()
val in = new BufferedSource(s.getInputStream()).getLines()
val out = new PrintStream(s.getOutputStream())
val filename = "mapReduce.jar"
for (line <- Source.fromFile(filename, "ISO-8859-1").getLines) {
out.println(line)
// println(line)
}
out.flush()
s.close()
}
}
Along with the Client:
object client extends App {
import java.net._
import java.io._
import scala.io._
import java.util.jar._
val s = new Socket(InetAddress.getByName("localhost"), 9999)
lazy val in = new BufferedSource(s.getInputStream()).getLines()
val out = new PrintStream(s.getOutputStream())
out.println("Give me the jar file!")
out.flush()
val file = new File("testmapReduce.jar")
val bw = new BufferedWriter(new FileWriter(file))
while(in.hasNext) {
val buf = in.next()
bw.write(buf)
// println(buf)
}
s.close()
bw.close()
println("Done!")
val jar = new JarFile(file) //this part fails
}
Source, PrintStream etc, are intended to deal with text, not binary data. They convert the data on both read and write in accordance with the character set they are using ("iso-8859-1" in your case).
Do not use them to read/write binary data.
If you just need to send byte, don't bother with interpreting them:
val f = new FileInputStream(filename)
val bos = new BufferedOutputStream(out)
Stream.continually(f.read).takeWhile(_ != -1).foreach(bos.write)
f.close
bos.close

Play Framework eating up disk space

I am successfully serving videos using the Play framework, but I'm experiencing an issue: each time a file is served, the Play framework creates a copy in C:\Users\user\AppData\Temp. I'm serving large files so this quickly creates a problem with disk space.
Is there any way to serve a file in Play without creating a copy? Or have Play automatically delete the temp file?
Code I'm using to serve is essentially:
public Result video() {
return ok(new File("whatever"));
}
Use Streaming
I use following method for video streaming. This code does not create temp copies of the media file.
Basically this code responds to the RANGE queries sent by the browser. If browser does not support RANGE queries I fallback to the method where I try to send the whole file using Ok.sendFile (internally play also tries to stream the file) (this might create temp files). but this happens very rarely when range queries is not supported by the browser.
GET /media controllers.MediaController.media
Put this code inside a Controller called MediaController
def media = Action { req =>
val file = new File("/Users/something/Downloads/somefile.mp4")
val rangeHeaderOpt = req.headers.get(RANGE)
rangeHeaderOpt.map { range =>
val strs = range.substring("bytes=".length).split("-")
if (strs.length == 1) {
val start = strs.head.toLong
val length = file.length() - 1L
partialContentHelper(file, start, length)
} else {
val start = strs.head.toLong
val length = strs.tail.head.toLong
partialContentHelper(file, start, length)
}
}.getOrElse {
Ok.sendFile(file)
}
}
def partialContentHelper(file: File, start: Long, length: Long) = {
val fis = new FileInputStream(file)
fis.skip(start)
val byteStringEnumerator = Enumerator.fromStream(fis).&>(Enumeratee.map(ByteString.fromArray(_)))
val mediaSource = Source.fromPublisher(Streams.enumeratorToPublisher(byteStringEnumerator))
PartialContent.sendEntity(HttpEntity.Streamed(mediaSource, None, None)).withHeaders(
CONTENT_TYPE -> MimeTypes.forExtension("mp4").get,
CONTENT_LENGTH -> ((length - start) + 1).toString,
CONTENT_RANGE -> s"bytes $start-$length/${file.length()}",
ACCEPT_RANGES -> "bytes",
CONNECTION -> "keep-alive"
)
}

Scala PDFBox error in code

Wrote a function for reading text from a PDF document.
Used scala language, Selenium, PDFBox 2.0.1.
Below is the code:
enter code here
import org.openqa.selenium.firefox.{FirefoxBinary, FirefoxDriver, FirefoxProfile}
import org.apache.pdfbox.pdfparser.PDFParser
import org.apache.pdfbox.text.PDFTextStripper
import java.io.BufferedInputStream
def pdfreaddata {
driver.get("https://www.....pdf")
driver.manage.timeouts.implicitlyWait(50, TimeUnit.SECONDS)
val url: URL = new URL(driver.getCurrentUrl)
println(url)
val fileToParse: BufferedInputStream = new BufferedInputStream(url.openStream())
val parser: PDFParser = new PDFParser(fileToParse)
parser.parse()
val output: String = new PDFTextStripper().getText(parser.getPDDocument)
println("pdf Value" + output)
parser.getPDDocument.close()
driver.manage.timeouts.implicitlyWait(100, TimeUnit.SECONDS)
}
Showing error for PDFParser in val parser: PDFParser = new PDFParser(fileToParse)
Error message:
Cannot resolve constructor
Tried the code in Java too, getting same error.
You are using PDFBox version 2.x, however you are obviously following the docs for version 1.x . In 2.0 there is no such constructor. Some things have changed, including parsing. Follow the migration guide or fall back to 1.8, since it does look much more documented and with more material online.
Using pdfbox 1.8.12 solved the constructor issue. But even the pdf's was not password protected, it was showing as encrypted. Below is the final code using Scala to extract encrypted text from a pdf document. Might be useful for someone in future.
def pdfreaddata {
driver.get("https://www....combo.pdf")
driver.manage.timeouts.implicitlyWait(50, TimeUnit.SECONDS)
val url: URL = new URL(driver.getCurrentUrl)
println(url)
val fileToParse: BufferedInputStream = new BufferedInputStream(url.openStream())
val parser: PDFParser = new PDFParser(fileToParse)
parser.parse()
val cosDocument:COSDocument = parser.getDocument()
val pdDocument:PDDocument = new PDDocument(cosDocument)
if(pdDocument.isEncrypted()) {
val sdm: StandardDecryptionMaterial = new StandardDecryptionMaterial(PDF_OWNER_PASSWORD)//PDF_OWNER_PASSWORD =""
pdDocument.openProtection(sdm)
}
val output: String = new PDFTextStripper().getText(pdDocument)
println("pdf Value" + output)
parser.getPDDocument.close()
driver.manage.timeouts.implicitlyWait(100, TimeUnit.SECONDS)
}
}

How to spawn a process in Scala with PTY?

In ruby I have:
PTY.spawn("/usr/bin/lxc-monitor -n .+") do |i, o, pid|
# ...
end
How do this in scala/java?
Try JPty or pty4j. These are implementations of pty for Java using JNA.
I don't think that PTY has been ported to java/scala. You can use the built in Runtime from java.
def run() {
val rt = Runtime.getRuntime
val cmds = Array("/usr/bin/lxc-monitor", "-n .+")
val env = Array("TERM=VT100")
val p1 = rt.exec(cmds, env)
}
I used this page as the base for the scala version.
UPDATE:
To get the output you need to get the input stream and read it (I know this sounds backwards but it's input relative to the jvm). The example below uses apache commons to skip some verbose parts of java.
import java.io.StringWriter
import org.apache.commons.io.IOUtils
class runner {
def run() {
val rt = Runtime.getRuntime
val cmds = Array("/usr/bin/lxc-monitor", "-n .+")
val env = Array("TERM=VT100")
val p1 = rt.exec(cmds, env)
val inputStream = p1.getInputStream
val writer = new StringWriter()
IOUtils.copy(inputStream, writer, "UTF-8")
val output = writer.toString()
println(output)
}
}
I got the apache utils idea from here.

Get queues depth from java code

Can anyone help in doing the code in java of getting the depth of the queues. We are having 4 queues in IBM WebSphere MQ and inside them there are messages.
I want to write a jsp to read the queue names and their depth while running the report. How do I do that?
Can anyone help in getting the full solution because I don't know what to do
I doens't think there is a way to retrieve the queue depth using JMS. You can however use MQ Series specific Java API to retrieve this information. Here is the sample code. Pay attention to int openOptions = MQC.MQOO_INQUIRE;
Here is the reference guide
int depth = 0;
MQQueueManager qMgr; // define a queue manager object
String mqHost = "";
String mqPort = "";
String mqChannel = "";
String mqQMgr = "";
String mqQueue = "";
try {
// Set up MQSeries environment
MQEnvironment.hostname = mqHost;
MQEnvironment.port = Integer.valueOf(mqPort).intValue();
MQEnvironment.channel = mqChannel;
MQEnvironment.properties.put(MQC.TRANSPORT_PROPERTY,
MQC.TRANSPORT_MQSERIES);
qMgr = new MQQueueManager(mqQMgr);
int openOptions = MQC.MQOO_INQUIRE;
MQQueue destQueue = qMgr.accessQueue(mqQueue, openOptions);
depth = destQueue.getCurrentDepth();
destQueue.close();
qMgr.disconnect();
} catch (Exception err) {
err.printStackTrace();
}
If you install the WMQ client from the IBM download (as opposed to just grabbing the class libs from the QMgr installation) you get sample code. Among the samples provided are several that list queue names, inquire on object properties and create objects. In a default installation on Win 7 these can be found at C:\Program Files (x86)\IBM\WebSphere MQ\tools\pcf\samples.
Download the WMQ client libraries here:
WMQ v6.0 is SupportPac MQC6 (End of life is September 2012)
WMQ v7.0 is SupportPac MQC7
WMQ v7.1 is SupportPac MQC71
The SupportPac landing page is here.
You are STRONGLY encouraged to use the latest WMQ client for any new development. It will work for all prior versions of WMQ at whatever level of functionality is provided by the target QMgr. Please see the Compatibility & Interop statement in the Infocenter. You can find the Infocenter for the WMQ version of server or client that you are using from the WMQ Library landing page.
A few of these functions are depreciated in IIB, so am pasting the updated code. It works :)
Enjoy
Getting MQ Queue Depth From Java:
try {
int depth = 0;
MQQueueManager qMgr; // define a queue manager object
String mqHost = "";
String mqPort = "";
String mqChannel = "";
String mqQMgr = "";
String mqQueue = "";
try {
// Set up MQSeries environment
MQEnvironment.hostname = mqHost;
MQEnvironment.port = Integer.valueOf(mqPort).intValue();
MQEnvironment.channel = mqChannel;
//MQEnvironment.properties.put(MQC.TRANSPORT_PROPERTY,MQC.TRANSPORT_MQSERIES);
qMgr = new MQQueueManager(mqQMgr);
//int openOptions = 1;//MQC.MQOO_INQUIRE;
int openOptions = CMQC.MQOO_INQUIRE + CMQC.MQOO_FAIL_IF_QUIESCING + CMQC.MQOO_INPUT_SHARED;
MQQueue destQueue = qMgr.accessQueue(mqQueue, openOptions);
depth = destQueue.getCurrentDepth();
destQueue.close();
qMgr.disconnect();
MbMessage outMessage = new MbMessage();
outAssembly = new MbMessageAssembly(inAssembly, outMessage);
MbElement root = outMessage.getRootElement();
MbElement outXmlRoot = root.createElementAsLastChild(MbXMLNSC.PARSER_NAME);
MbElement Appointment = outXmlRoot.createElementAsLastChild(MbElement.TYPE_NAME, "RootElementXMLName", null);
Appointment.createElementAsLastChild(MbElement.TYPE_NAME_VALUE, "Q_DepthFromServer", depth);
out.propagate(outAssembly);
}

Categories