If there is data, how is the stream returning zero bytes? - javafx

I have a RXTX project that I'm working on. I have it set ups as follows:
public void doConnect(ActionEvent event)
{
String selectedPort = (String)connectTabController.portList.getValue();
System.out.println("Connecting to: " + selectedPort);
selectedPortIdentifier = (CommPortIdentifier)portMap.get(selectedPort);
CommPort commPort = null;
try
{
commPort = selectedPortIdentifier.open("AT QC ReponseTime", TIMEOUT);
serialPort = (SerialPort)commPort;
setConnected(true);
if (isConnected)
{
if (initIOStream() == true)
{
initListener();
System.out.println("Initializing listener");
connectTabController.gui_changeStatusLabel("Device Connected!");
}
}
}
catch (PortInUseException e)
{
System.out.println("Port In use! " + e.toString());
}
catch (Exception e)
{
System.out.println("Failed to open! " + e.toString());
}
}
public boolean initIOStream()
{
//return value for whether opening the streams is successful or not
boolean successful = false;
try {
//
input = serialPort.getInputStream();
output = serialPort.getOutputStream();
writeData(RESETTPOD);
System.out.println("Writing Reset command");
successful = true;
System.out.println("IO Stream opened successfully!");
return successful;
}
catch (IOException e) {
System.out.println("I/O Streams failed to open. (" + e.toString() + ")");
return successful;
}
}
public void initListener()
{
try
{
serialPort.addEventListener(this);
serialPort.notifyOnDataAvailable(true);
}
catch (TooManyListenersException e)
{
System.out.println("Too many listeners. (" + e.toString() + ")");
}
}
That's how the connection is made, and it has a listener that's supposed to notify when data is available, which triggers the following:
#Override
public void serialEvent(SerialPortEvent evt) {
BufferedReader reader = null;
if (evt.getEventType() == SerialPortEvent.DATA_AVAILABLE)
{
try
{
reader = new BufferedReader(new InputStreamReader(input));
if (reader.ready())
{
fullLine = reader.readLine();
System.out.println(fullLine + "\n");
}
}
catch (Exception e)
{
System.out.println("#SerialEvent Failed to read data. (" + e.toString() + ")");
}
}
}
However, I keep getting "UNDERLYING INPUT STREAM RETURNED ZERO BYTES"
This makes no sense, since if there is nothing to read then the listener shouldnt be triggered int he first place. I tried running the app and I keep getting this error message around every 1/3 second, which corresponds to the burst-output of the device that's sending data. (which works fine in programs like PuttY)

If you are going to use the BufferedReader, take a look at the refence API document for javax.comm, CommPort and getInputStream. Then try using different settings for threshold and receive timeout.
eg).
serialPort.enableReceiveThreshold(3);
serialPort.enableReceiveTimeout(1);
https://docs.oracle.com/cd/E17802_01/products/products/javacomm/reference/api/

Related

Thread disrupting execution of ASP.net main application

I have an ASP.net web app that spawns a process (in a thread). This thread calls a '.dll' to connect to another 'subsystem'.
Problem is, when there are errors connecting to the 'subsystem', it affects my main application (main UI) and I get a 'connection refused message'. I have already put in 'try-catch' error handling routines in my thread. FYI, I would like to treat the thread as a 'Fire and forget' thread.
The thread is spawned when btnSubmit is clicked.
Please refer to trimmed-down extract of code.
protected void btnSubmit_Click(object sender, EventArgs e)
{
try
{
txt_hide.Value = sStatus;
if (sStatus == "")
{
//create thread for posting
id = Guid.NewGuid();
Thread th = new Thread(() => postXMLClass.PostXML(sSeqNo));
th.Start();
sStatus = "Transaction generated..please check posting status..";
lblMessage.Text = "Transaction Generated...";
}
else
{
FormView1.DataBind(); //refresh the form
clib.Show2("Error generating transaction : " + sStatus, sender);
lblMessage.Text = "Error generating transaction : " + sStatus;
}
}
catch (SqlException ex)
{
lblMessage.Text = "Error generating transaction ...: " + ex.Message;
}
catch (Exception ex)
{
//sqc.Transaction.Rollback();
lblMessage.Text = "Error encountered...: " + ex.Message;
throw;
}
finally
{
if (dbc != null) dbc.Dispose();
if (clib != null) clib.Dispose();
}
}
public static void PostXML(string inlinkcode)
{
string sToken = "", sXMLOut = "";
Xml.Router.XMLRouter cX = new Xml.Router.XMLRouter();
try
{
cX.set_Options("com.xml.router.nameServer", appSetArray[0]);
cX.set_Options("com.xml.router.nameServerPort", appSetArray[2]);
cX.set_Options("com.xml.router.logicalServerName", appSetArray[1]);
{
sLinkcode = inlinkcode;
if (sLinkcode != null && sLinkcode != "")
{
strxml = "<?xml version=\"1.0\" encoding='UTF-8' ?>";
strxml += "<TableLinkRequest version=\"1.0\"><DocumentLinkStart><Request><StartParams>";
strxml += "<CmpCode>X</CmpCode><DocCode></DocCode></TableLinkRequest>";
sXMLOut = cX.Send(sToken, strxml);
}
}
}
catch (Exception ex)
{
Console.WriteLine("Exception {0}", ex.Message);
}
finally
{
if (cX != null) cX.Logoff(sToken);
}
}

File Encryption with the Java Cryptography Architecture using AES with a 128-bit key and PBKDF2

I am getting this error when I am decrypting a file
I am using PBKDF2 to convert a passphrase to a key and then using it. The encryption is working good but when I am trying to decrypt the same file it is giving the below error. The decrypted file gives a correct data except for the last few lines(probably the padding area). I have debugged it by outputting the IV and key while encrypting and decrypting and they both are the same but the error still exists.
public class FileEncryptorSkeleton{
private static final String progName = "FileEncryptor";
private static final int bufSize = 128;
/**
* #param args
*/
public static void main(String[] args) throws UnsupportedEncodingException {
BufferedInputStream in = null; // A buffered input stream to read from
BufferedOutputStream out = null; // And a buffered output stream to write to
SecretKeyFactory kf = null; // Something to create a key for us
KeySpec ks = null; // This is how we specify what kind of key we want it to generate
byte[] salt = new byte[20]; // Some salt for use with PBKDF2, only not very salty
SecretKey key = null; // The key that it generates
Cipher cipher = null; // The cipher that will do the real work
SecretKeySpec keyspec = null; // How we pass the key to the Cipher
int bytesRead = 0; // Number of bytes read into the input file buffer
byte[] iv = new byte[16];
// First, check the user has provided all the required arguments, and if they haven't, tell them then exit
if(args.length != 4) {
printUsageMessage(); System.exit(1);
}
// Open the input file
try {
in = new BufferedInputStream(new FileInputStream(args[1]));
} catch (FileNotFoundException e) {
printErrorMessage("Unable to open input file: " + args[1], null);
System.exit(1);
}
// And then the output file
try {
out = new BufferedOutputStream(new FileOutputStream(args[2]));
} catch (FileNotFoundException e) {
printErrorMessage("Unable to open output file: " + args[2], e);
System.exit(1);
}
try {
kf = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1");
} catch (NoSuchAlgorithmException ex) {
Logger.getLogger(FileEncryptorSkeleton.class.getName()).log(Level.SEVERE, null, ex);
}
// Set up a KeySpec for password-based key generation of a 128-bit key
ks = new PBEKeySpec(args[3].toCharArray(), salt, 1000, 128);
// Now run the passphrase through PBKDF2 to get the key
try {
key = kf.generateSecret(ks);
}catch(InvalidKeySpecException e){
System.exit(1);
}
// Get the byte encoded key value as a byte array
byte[] aeskey = key.getEncoded();
// Now generate a Cipher object for AES encryption in ECBC mode with PKCS #5 padding
// Use ECB for the first task, then switch to CBC for versions 2 and 3
try {
cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
} catch (NoSuchAlgorithmException e) {
printErrorMessage("No Such Algorithm Exception when creating main cipher", e);
System.exit(2);
} catch (NoSuchPaddingException e) {
printErrorMessage("No Such Padding Exception when creating main cipher",e);
System.exit(2);
}
// Set a variable to indicate whether we're in encrypt or decrypt mode, based upon args[0]
int cipherMode = -1;
char mode = Character.toLowerCase(args[0].charAt(0));
switch (mode) {
case 'e' : cipherMode = Cipher.ENCRYPT_MODE; break;
case 'd' : cipherMode = Cipher.DECRYPT_MODE; break;
default: printUsageMessage(); System.exit(1);
}
// Set up a secret key specification, based on the 16-byte (128-bit) AES key array previously generated
keyspec = new SecretKeySpec(aeskey, "AES");
IvParameterSpec ivspec = new IvParameterSpec(iv);
// Now initialize the cipher in the right mode, with the keyspec and the ivspec
try {
cipher.init(cipherMode, keyspec,ivspec);
} catch (InvalidKeyException e) {
printErrorMessage("Invalid Key Spec",e); System.exit(2);
} catch (InvalidAlgorithmParameterException ex) {
Logger.getLogger(FileEncryptorSkeleton.class.getName()).log(Level.SEVERE, null, ex);
}
// Set up some input and output byte array buffers
byte[] inputBuffer = new byte[bufSize];
byte[] outputBuffer = null;
// "Prime the pump" - we've got to read something before we can encrypt it
// and not encrypt anything if we read nothing.
try {
bytesRead = in.read(inputBuffer);
} catch (IOException e) {
printErrorMessage("Error reading input file " + args[1],e); System.exit(1);
}
// As long as we've read something, loop around encrypting, writing and reading
// bytesRead will be zero if nothing was read, or -1 on EOF - treat them both the same
while (bytesRead > 0) {
// Now encrypt this block
outputBuffer = cipher.update(inputBuffer.toString().getBytes("UTF-8"));
// Write the generated block to file
try {
out.write(outputBuffer);
} catch (IOException e) {
printErrorMessage("Error writing to output file " + args[2],e); System.exit(1);
}
// And read in the next block of the file
try {
bytesRead = in.read(inputBuffer);
} catch (IOException e) {
printErrorMessage("Error reading input file " + args[1],e); System.exit(1);
}
}
try {
// Now do the final processing
outputBuffer =cipher.doFinal(inputBuffer.toString().getBytes("UTF-8"));
cipher.init(cipherMode, keyspec,ivspec);
System.out.println(ivspec+" "+cipherMode+" "+keyspec);
} catch (IllegalBlockSizeException ex) {
Logger.getLogger(FileEncryptorSkeleton.class.getName()).log(Level.SEVERE, null, ex);
} catch (BadPaddingException ex) {
Logger.getLogger(FileEncryptorSkeleton.class.getName()).log(Level.SEVERE, null, ex);
} catch (InvalidKeyException ex) {
Logger.getLogger(FileEncryptorSkeleton.class.getName()).log(Level.SEVERE, null, ex);
} catch (InvalidAlgorithmParameterException ex) {
Logger.getLogger(FileEncryptorSkeleton.class.getName()).log(Level.SEVERE, null, ex);
}
// Write the final block of output
try {
out.write(outputBuffer);
} catch (IOException e) {
printErrorMessage("Error on final write to output file " + args[2],e); System.exit(1);
}
// Close the output files
try {
in.close();
out.close();
} catch (IOException e) {
printErrorMessage("Error closing file", e);
}
// If we were continuing beyond this point, we should really overwrite key material, drop KeySpecs, etc.
}
/**
* Print an error message on , optionally picking up additional detail from
* a passed exception
* #param errMsg
* #param e
*/
private static void printErrorMessage(String errMsg, Exception e) {
System.err.println(errMsg);
if (e != null)
System.err.println(e.getMessage());
}
/**
* Print a usage message
*/
private static void printUsageMessage() {
System.out.println(progName + " $Revision: 1.1 $: Usage: " + progName + " E/D infile outfile passphrase");
}
}
Oct 18, 2019 11:27:46 PM FileEncryptorSkeleton main
SEVERE: null
javax.crypto.BadPaddingException: Given final block not properly padded. Such issues can arise if a bad key is used during decryption.
at com.sun.crypto.provider.CipherCore.unpad(CipherCore.java:975)
at com.sun.crypto.provider.CipherCore.fillOutputBuffer(CipherCore.java:1056)
at com.sun.crypto.provider.CipherCore.doFinal(CipherCore.java:853)
at com.sun.crypto.provider.AESCipher.engineDoFinal(AESCipher.java:446)
at javax.crypto.Cipher.doFinal(Cipher.java:2164)
at FileEncryptorSkeleton.main(FileEncryptorSkeleton.java:174)
Both the Cipher#update- and Cipher#doFinal-method use inputBuffer.toString(), which only contains the name of the object's class and the hashcode and not the actual data in the buffer.
It would be correct to read the first bytesRead bytes from the inputBuffer-byte[] (which were previously read from the in-BufferedInputStream) and process them (Cipher#update):
outputBuffer = cipher.update(inputBuffer, 0, bytesRead);
The loop containing the cipher#update-call is only left when no byte has been read to the inputBuffer-byte[], so that for the final processing applies (Cipher#doFinal):
outputBuffer = cipher.doFinal();
In addition, the second cipher#init-call immediately after the cipher#doFinal-call is unnecessary (Cipher#init).

DownloadFileAsync with webclient issue

I am trying to download file from FTP using Webclient DownloadFileAsync method. i have used below code
private bool DownloadFileFromFtp()
{
try
{
MyWebClient client = new MyWebClient();
Uri ftpurl = new Uri("ftp://MyFtpserver/Filename.pdf");
client.Credentials = new NetworkCredential("Userid", "mypassword");
client.DownloadProgressChanged += Client_DownloadProgressChanged;
client.DownloadDataCompleted += Client_DownloadDataCompleted;
client.DownloadFileAsync(ftpurl, #"D:\RTP\Filename.pdf");
return true;
}
catch (Exception ex)
{
return false;
}
}
private void Client_DownloadProgressChanged(object sender, DownloadProgressChangedEventArgs e)
{
double bytesIn = double.Parse(e.BytesReceived.ToString());
double totalBytes = double.Parse(e.TotalBytesToReceive.ToString());
double percentage = bytesIn / totalBytes * 100;
lbldatareceived.Text = bytesIn + "/" + totalBytes;
lblPercentage.Text = percentage+"%";
FileProgress.Attributes.CssStyle.Add("width", Convert.ToString(percentage) + '%');
FileProgress.Attributes.Add("aria-valuenow", Convert.ToString(percentage));
}
private void Client_DownloadDataCompleted(object sender, DownloadDataCompletedEventArgs e)
{
throw new NotImplementedException();
}
When I run this code file download gets starts and browser start loading. How can I download files without loading a browser?

JavaFX TextArea appendText works in initialize but not elsewhere

Simple enough problem but it's been driving me crazy.
In my program I have a TextArea, defined as:
<TextArea fx:id="output" editable="false" prefHeight="300.0" prefWidth="200.0" text="Output" GridPane.columnSpan="2" GridPane.rowIndex="4" />
#FXML private TextArea output;
...
public void initialize(URL url, ResourceBundle rb) {
output.setText("Test"); //Test appears correctly in output
...
}
#FXML
public void download() {
String outputTemplate = templateField.getText();
String url = urlField.getText();
System.out.println("Downloading from " + url);
try {
Process down = Runtime.getRuntime().exec("youtube-dl -o \"" + outputTemplate + "\" " + url);
BufferedReader reader = new BufferedReader(new InputStreamReader(down.getInputStream()));
String line;
while ((line = reader.readLine()) != null) {
System.out.println(line); //Prints as expected
output.appendText(line + "\n"); //Has no effect
}
} catch (IOException e) {
e.printStackTrace();
}
}
Any ideas on how to get the text to appear would be great, I've done this before on different programs, just for some reason, this time it's being cantankerous
EDIT: Upon further tinkering, it actually will print out the results, but only after the Process ends and it exits the loop.
The text shown in the UI changes on a layout pulse. Layout pulses are done on the JavaFX application thread. Event handlers, like your download method run on the same thread effectively preventing it from doing any layouting or processing and other events until it completes. This is why you shouldn't block this thread with longrunning tasks, but execute them on a different thread.
Since updates to the UI should be done from the application thread, use Platform.runLater to append the text:
#FXML
public void download() {
String outputTemplate = templateField.getText();
String url = urlField.getText();
Runnable r = () -> {
System.out.println("Downloading from " + url);
try {
Process down = Runtime.getRuntime().exec("youtube-dl -o \"" + outputTemplate + "\" " + url);
BufferedReader reader = new BufferedReader(new InputStreamReader(down.getInputStream()));
String line;
while ((line = reader.readLine()) != null) {
System.out.println(line); //Prints as expected
final String printText = line + "\n";
// append the line on the application thread
Platform.runLater(() -> output.appendText(printText));
}
} catch (IOException e) {
e.printStackTrace();
}
};
// run task on different thread
Thread t = new Thread(r);
t.start();
}
The problem is that you're doing this in the main thread. So stage can not be updated, until the cycle is finished. Try it in new thread:
#FXML
public void download() {
Task<Void> task = new Task<Void>() {
#Override
protected Void call() {
String outputTemplate = templateField.getText();
String url = urlField.getText();
System.out.println("Downloading from " + url);
try {
Process down = Runtime.getRuntime().exec("youtube-dl -o \"" + outputTemplate + "\" " + url);
BufferedReader reader = new BufferedReader(new InputStreamReader(down.getInputStream()));
String line;
while ((line = reader.readLine()) != null) {
System.out.println(line); // Prints as expected
output.appendText(line + "\n"); // Has no effect
}
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
};
new Thread(task).start();
}

Datatype mismatch for blob type blackberry

I have an exception that Datatype mismatch in this line
byte[] _data = (byte[])row.getBlobBytes(1);
and in the table I have the type of column 2 is BLOB.
public static UrlRsc getContentUrl(String name) {
UrlRsc elementRsc = null;
try {
Statement statement = DB
.createStatement("SELECT * FROM table where"
+ " Name='"
+ name + "'");
statement.prepare();
Cursor cursor = statement.getCursor();
Row row;
while (cursor.next()) {
row = cursor.getRow();
byte[]_data;
_data = row.getBlobBytes(1);
}
statement.close();
cursor.close();
} catch (DatabaseException dbe) {
System.out.println(dbe.toString());
} catch (DataTypeException dte) {
System.out.println(dte.toString());
}
return elementRsc;
}
Can any one help me ?
Hi i am using following code for save image in my local database and i got success. i just posted my 3 methods
Note: When i am inserting image into data base i changed that image in byte array then only i can save into that table
1)Table creation 2) table insertion 3)image retrieving from table
ContactImage_table creation
public ContactImageTableCreation(){
try{
Statement stmt=DATABASE.createStatement("create table if not exists 'ContactImage_table'(ID 'TEXT',image 'blob',NodeId 'TEXT')");
stmt.prepare();
stmt.execute();
stmt.close();
}catch(Exception e){
System.out.println(e.getMessage());
}
}
Insert data into ContactImage_table
public void ContactImageTableInsertion(){
try{
Statement st=DATABASE.createStatement("insert into ContactImage_table (ID,Image,NodeId)values(?,?,?)");
st.prepare();
st.bind(1, "101");
st.bind(2, BYTE_ARRY);
st.bind(3,"103");
st.execute();
st.close();
}catch (Exception e) {
System.out.println(e.getMessage());
}
}
Retrieving data from ContactImage_table
public ContactImageTableDataRetriving(){
try{
Statement st=DATABASE.createStatement("select * from ContactImage_table");
st.prepare();
Cursor c=st.getCursor();
Row r;
int i=0;
while(c.next()){
r=c.getRow();
i++;
// ContactImageObject is a wrapper class for data handling
contactImageObj=new ContactImageObject();
contactImageObj.setId(r.getString(0));
byte[] decoded=r.getBlobBytes(1);
EncodedImage fullImage = EncodedImage.createEncodedImage(decoded, 0, decoded.length);
Bitmap b=fullImage.getBitmap();
contactImageObj.setImage(b);
// System.out.println("Successfully retrived");
if(i==0){
// System.out.println("No Records");
}
}
st.close();
}catch (Exception e) {
// System.out.println(e.getMessage());
}
}
just cross check your code with this code snippet hope you will get resolve all the best

Resources