Validate the DB2 command's output on Japenese/Chinese machine - java

The application works fine on Windows machines where DB2 is setup in English language, since need to validate the executed commands output like
> db2 attach to DB2 user db2admin using xxxxxx
Instance Attachment Information
Instance server = DB2/NT64 10.5.1
Authorization ID = DB2ADMIN
Local instance alias = DB2
Actually the above output is redirected into a text file and then validated by a Java code as
String message = Utils.readFile(filePath);
message = message.trim().replaceAll("\\s+", " ");
String upperStr = message.toUpperCase();
if (upperStr.indexOf("INSTANCE ATTACHMENT INFORMATION") != -1
&& upperStr.indexOf("AUTHORIZATION ID") != -1)
return "SUCCESS";
else
return "FAILURE";
But the issue is: On Japanese/Chinese machine the DB2 commands generate the output in their language e.g. In Japanese Machine
インスタンス?Eアタッチ?﨣・インスタンス?Eサ?[バ?[ = DB2/NT 10.5.5 許可 ID = DB2ADMIN ・?[カル?Eインスタンス別名 = DB2
So, how to modify that language to work normally like English?
Or could the command's output be generated in English only?

It seems that you chose an unreliable way to determine success (or failure) of an external program. Apart from the language problem you are dealing with, there are other possible issues with trying to save and parse program output.
A better way to check the external program result is to look at its exit code. By convention, most programs (DB2 CLP included) return 0 when they end successfully and a different value if there is some sort of a problem. You can find more information in the manual.
When executing an external program from Java, you can use Process.exitValue() to obtain its exit code.

Related

Java jar execution discrepancies between machines

I wrote a bit of code that verifies the contents of a comma delimited file by checking each field against some regular expression - the particular regex that is causing me grief is a very basic date regex (\\d{2}/\\d{2}/\\d{2}). If the data in that field doesn't match, it's supposed to write out to a separate file indicating that it needs to be inspected, like so:
private static int DATE_FIELD = 5;
File input = new File("input.txt");
Pattern p = Pattern.compile("\\d{2}/\\d{2}/\\d{2}");
BufferedReader reader = new BufferedReader(new FileReader(input));
String line = reader.readLine();
while(line != null){
String[] splitLine = line.split(",");
Matcher m = p.matcher(splitLine[DATE_FIELD]);
if(!m.matches) {
// write warning to separate file
}
line = reader.readLine();
}
This code is compiled as part of a larger JAR file which is installed on 4 computers in the office (mine and three others). The jar file is invoked via a shell call made by a separate program, passing in the relevant parameters. This is part of a QC check before we import the data into our database, and the date is a required field, so if the date field was left blank, it should be flagged for review.
The regex that I used should not allow for a blank date to pass, and when I run it on my machine, it properly flags the missing dates. However, on my coworkers machines, the blank dates were somehow not flagged, as if the field wasn't checked at all, which caused a little grief when the file was being imported into the database.
In other words, there is some discrepancy between our machines that caused the code to execute incorrectly on their machines, but not mine. All of the machines have Java 8 (not sure exactly which version, but they should all be the same version). How can that be?
You need to specify the encoding of the file(s) you want to read.
[The constructors of FileReader] generally use the platform default encoding. So determine the actual encoding and use something like new InputStreamReader(new FileInputStream(input), <encoding>)
Check the java version for each machine. Verify that the designated java is actually called
Check the encoding of the file(s) itself (UTF-8, CP1252, or ...)

How to pass argument to Java Process?

I have a Java application that creates and runs a process (x.exe). When process x is executed, it prompts the user to enter a password. How to pass this password to the user?
I tried to use the OutputStream of the process and wrote the password to the stream but still the process didn't run.
Runtime r=Runtime.getRuntime();
Process p=r.exec("x.exe");
p.getOutputStream()//.use to pass the arguments
You need to flush the stream, and also, it maybe expects a CR at the end of the password to simulate the ENTER key the user types at the end of the password. This works for me in Linux:
Runtime r = Runtime.getRuntime();
Process p = r.exec("myTestingExe");
p.getOutputStream().write("myPassword\n".getBytes()); // notice the `\n`
p.getOutputStream().flush();
Some caveats:
This works in Linux with '\n' at the end, maybe in Windows you would need \r instead (honestly I'm not sure of how Windows handles the "ENTER" key in the input)
I'm using "myPassword\n".getBytes() but a more complete value would be new String("myPassword".getBytes(), Charset.forName("MyCharsetName")); (where "MyCharsetName" is a supported encoding) if you are using an encoding like "UTF-8".
As already was pointed out you can consider to use an Expect-like library for interacting between your Java program and a spawn OS process. Basically, you would need to wait until the password prompt gets available in the process input stream and then write the password terminated by the end-of-line to the process output stream.
If you decide to go with a third party library approach I'd recommend you to give a try my own modern alternative to expect4j and others. It is called ExpectIt has no dependencies and is Apache licensed.
Here is a possible example with the use of the expect library:
Process process = Runtime.getRuntime().exec("...");
Expect expect = new ExpectBuilder()
.withInputs(process.getInputStream())
.withOutput(process.getOutputStream())
.withErrorOnTimeout(true)
.build();
expect.expect(contains("Password:"));
expect.sendLine("secret");
expect.close();
Note: the contains method is statically imported.
You can try library like expect4j to interact with the external process

Remove special characters while using "more" command from Java using JSCH?

I have a log file on a UNIX server which is dynamically changing.
I want to build an application to view that file on a Java GUI using Swings in multiple pages using SSH.
I am using JSCH Library to execute the "more" command for that log file. But in the output, some special characters like '[24;1H[K[7m' are printed. How to remove these special characters.
I am using the following code
session.setConfig("StrictHostKeyChecking", "no");
session.connect(30000);
Channel channel=session.openChannel("shell");
channel.setInputStream(System.in);
channel.setOutputStream(System.out);
channel.connect();
Thread.sleep(3000);
PrintStream ps = new PrintStream(channel.getOutputStream(), true);
ps.println("more " + fileName);
The output is :
[?7h[?1l(B=[24;1H[K************ Start Display Current Environment ************
[24;1H[K[7mSystemOut.log (0%)[m[24;1H[24;1H[KID: soacore.FP6123 BuildVrsn: null Desc: WebSphere Process Server 6.1.2.3
[24;1H[K[7mSystemOut.log (0%)[m
As you can see, some special characters are printed. How to remove those special characters?
I found out the answer. Just one line of code does the trick.
((ChannelShell) channel).setPtyType("dumb");
Adding the above line before the connect() removes all the non printable characters.
If you are developing a terminal emulator you can consider using a third-party library that could help you to manage the input data flow, specially dealing with the ANSI terminal control characters you are encountering. Tools like Expect are traditionally used to automate interacting between a program and text based terminal systems.
There are several exiting Expect for Java implementations you can use. Here I'd like to promote my own open source tool called ExpectIt. It supports filtering the input data to remove unwanted characters like terminal control that you may find very useful for your use case. It has other advantages stated on the project page.
Here is an example of using ExpectIt to iterate through the results of the more command. Note registering the removeColors filter which filters out the terminal characters.
session.setConfig(config);
session.connect();
Channel channel = session.openChannel("shell");
Expect expect = new ExpectBuilder()
.withOutput(channel.getOutputStream())
.withInputs(channel.getInputStream(), channel.getExtInputStream())
// register filters to remove ANSI color characters
.withInputFilters(removeColors())
.build();
try {
channel.connect();
// define the command line prompt
final String PROMPT = "...";
expect.expect(contains(PROMPT));
expect.sendLine("more <file>");
while (true) {
// expect either the end of the page or the end of the command
MultiResult result = expect.expect(anyOf(contains("--More--"), contains(PROMPT)));
// print the result
System.out.println(result.getBefore());
// exit if reach the end
if (result.getResults().get(1).isSuccessful()) {
break;
}
// scroll to the next page
expect.send(" ");
}
The code below works assuming that the corresponding methods are imported statically.

Using PHP to supply an in memory pdf from a Java generator

I am creating a web front end for clients to download their reports. The program that the company uses is written in Java and consists of 31 mysql tables with the 4 reports needed having over 140 points of data each. I am making the website in PHP and report generator in Java but I am having an issue finding the information on how to get the in memory PDF to load directly in the clients browser. I figured on using a TCP client/server going from Java to PHP but how do I code it so that it doesn't have to be written to the server drive and be supplied as a link. I also have no wish to rewrite 17,000 lines of Java to PHP as I am new to PHP. Is there anyway to get this done?
Thank you in advance.
Depending on how long the java app would take to run, you could consider using proc_open to create a pipe to the java programme:
<?php
$desc = array(array('pipe','r'),array('pipe','w'));
$resource= proc_open('bash',$desc,$pipes);
if (!is_resource($resource))
{
throw new Exception('PDF stream creation failed');
}
usleep(5);//for safety
fwrite($pipes[0],'java mkPDF paras'."\n");//double quoted \n is crucial
fclose($pipes[0]);
usleep(100);//while java app is running;
$pdf = stream_get_contents($pipes[1]);
fclose($pipes[1]);
proc_close($resource);
?>
This is just a basic example, that gets the streamed pdf in one big lump, so it's far from perfect. What you -IMO- should look into is getting the stream in chunks using a while loop. The php man page contains a couple of examples of this, basically, repleace
usleep(100);//while java app is running;
$pdf = stream_get_contents($pipes[1]);
with:
usleep(10);//while java app is running;
$pdf = '';
while (($pdfBuff = fgets($pipes[1],1024)) !== null)
{
$pdf.=$pdfBuff;//or echo, or whatever
}
fclose($pipes[1]);
The latter is untested, so I'm not sure if that will work in your case... but you get the idea
As said by #Elias directly send web request to java application and stream the pdf to php.
Using web services,
I. Develop some web services on java side that will send only data in any of the format like XML, jSon etc.
II. Write a code to consume these web services and develop your code to generate the pdf and stream these pdf's.
There is one pdf generating lib. Please find the link here

how to display registered trademark symbol ® in unix

How to display registered trademark symbol ® unix environment.
In this symbol working in window environment, but it not working unix environment.I am having paragraph in java file.displaying this symbol when working in windows environment, but move to unix(server) symbol not displaying in the format(®).
String str="stackoverflow ® ";
This is message sending email to customers.When running program in windows sending email correct format.But when running in unix(server) not sending correct format.
What is problem here ?
When sending email from window system that email displaying correct format.But not unix system.
Example:
original message="stackoverflow ®"
Getting email message="stackoverflow ÿ"
What is resaon behind in this ?
this sending email message.
I suspect that the problem is in the way that you are constructing and / or sending the mail message; e.g. in the content type / character set that you are specifying. But we can only guess, unless you post the relevant code ...
As #Paŭlo Ebermann suggests, if you are embedding a special character directly in your code, then you can run into compilation problems if the compiler reads your source code using the wrong character set / encoding. You can avoid these problems entirely by using Unicode escapes; e.g. change your code to say:
String message = "stackoverflow \u00AE";
instead of
String message = "stackoverflow ®";
IMO, this is a good idea ... even if this is not what is causing your problem.
One possible cause could be the email construction, as Stephen C said.
Another possible cause would be the compilation - the compiler uses the default character set of your system if you don't indicate something else, and this default character set could be different on windows and your unix system.
Look how the source file is encoded, and supply this with the -encoding parameter to the compiler.
Alternatively, to be encoding independent, you could write \u00AE in the source code instead.

Categories