I've been searching for a solution for this problem for 2 days now..
I have an android chat application that I want to implement sending files into it.
Here's the sending code:
public void sendFile(Uri uri) {
FileTransferManager fileTransferManager = FileTransferManager.getInstanceFor(app.getConnection());
OutgoingFileTransfer fileTransfer = fileTransferManager.createOutgoingFileTransfer(userId + "/Spark");
try {
fileTransfer.sendFile(new File(uri.getPath()), "this is the description");
System.out.println("status is:" + fileTransfer.getStatus());
System.out.println("sent .. just");
while (!fileTransfer.isDone()) {
if (fileTransfer.getStatus() == FileTransfer.Status.refused) {
Toast.makeText(getActivity(), "File refused.", Toast.LENGTH_SHORT).show();
return;
}
if (fileTransfer.getStatus() == FileTransfer.Status.error) {
Toast.makeText(getActivity(), "Error occured.", Toast.LENGTH_SHORT).show();
return;
}
}
System.out.println(fileTransfer.getFileName() + "has been successfully transferred.");
System.out.println("The Transfer is " + fileTransfer.isDone());
} catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
}
}
I know this code works fine as I sent file from android to spark and received it successfully.. The problem is in receiving that file in android.. Here's the code:
ProviderManager.addIQProvider("si", "http://jabber.org/protocol/si",
new StreamInitiationProvider());
ProviderManager.addIQProvider("query", "http://jabber.org/protocol/bytestreams",
new BytestreamsProvider());
ProviderManager.addIQProvider("open", "http://jabber.org/protocol/ibb",
new OpenIQProvider());
ProviderManager.addIQProvider("close", "http://jabber.org/protocol/ibb",
new CloseIQProvider());
ServiceDiscoveryManager sdm = ServiceDiscoveryManager.getInstanceFor(connection);
sdm.addFeature("http://jabber.org/protocol/disco#info");
sdm.addFeature("jabber:iq:privacy");
final FileTransferManager manager = FileTransferManager.getInstanceFor(connection);
manager.addFileTransferListener(new FileTransferListener() {
public void fileTransferRequest(FileTransferRequest request) {
IncomingFileTransfer transfer = request.accept();
try {
File file = new File(Environment.getExternalStorageDirectory() + "/" + request.getFileName());
Log.i("Tawasol", "File Name: " + request.getFileName());
transfer.recieveFile(file);
while (!transfer.isDone() || (transfer.getProgress() < 1)) {
Thread.sleep(1000);
Log.i("Tawasol", "still receiving : " + (transfer.getProgress()) + " status " + transfer.getStatus());
if (transfer.getStatus().equals(org.jivesoftware.smackx.filetransfer.FileTransfer.Status.error)) {
// Log.i("Error file",
// transfer.getError().getMessage());
Log.i("Tawasol",
"cancelling still receiving : "
+ (transfer.getProgress())
+ " status "
+ transfer.getStatus() + ": " + transfer.getException().toString());
transfer.cancel();
break;
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
});
still receiving : 0.0 status Negotiating Stream
I get this log for about 5 seconds the I get that:
cancelling still receiving : 0.0 status Error: org.jivesoftware.smack.SmackException: Error in execution
I think that the problem is in the openfire server that I'm using.. I've openfire 3.9.3 server installed on my windows 7 64bit.. In the Smack logs I noticed this one:
<iq id="L87BF-73" to="59xrd#rightsho/Smack" type="set" from="h97qa#rightsho/Spark"><query xmlns="http://jabber.org/protocol/bytestreams" sid="jsi_4840101552711519219" mode="tcp"><streamhost jid="proxy.rightsho" host="192.168.56.1" port="7777"/></query></iq>
The host here is 192.168.56.1 which I think is local ip so that I can't access it from android.. So I wan't to use the IP of the pc to transfer files..
Excuse me for my lack of knowledge in this field.
From my little knowledge of smack the issue may be in this piece of code:
while (!transfer.isDone() || (transfer.getProgress() < 1)) {
Thread.sleep(1000);
Log.i("Tawasol", "still receiving : " + (transfer.getProgress()) + " status " + transfer.getStatus());
if (transfer.getStatus().equals(org.jivesoftware.smackx.filetransfer.FileTransfer.Status.error)) {
// Log.i("Error file",
// transfer.getError().getMessage());
Log.i("Tawasol",
"cancelling still receiving : "
+ (transfer.getProgress())
+ " status "
+ transfer.getStatus() + ": " + transfer.getException().toString());
transfer.cancel();
break;
}
}
If you move the monitoring while loop to another thread, suddenly this error goes away. I'm not sure why, but it has worked for me and my friends in the past.
Related
I have been using Javamail (version 1.6.4) for a while now, mostly for event listening, mail parsing and copy/delete mails (from Exchnage using IMAPS). Lately i was asked to use sub-folders for a business usecase. When moving mail from the Inbox folder to a sub-folder the UID changes so i'm using folder.search() in order to find the new UID. This works most of the times but sometimes the search goes indefnitley (or its duration is very long) which may lag the entire application.
Is there a way to set a timeout (or other way to throw an exception if it runs too long) for folder.search()?
I understood that imap search is done on the server side but i just wanted to validate. this is an example of how i send search to the server (we can assume subject is unique for this discussion):
private static String findMailIdBySubject(String mailbox, String srcFolder, String subject) {
Folder srcFolderObj = null;
boolean wasConnectionEstablished = connectToMail(mailbox);
if (!wasConnectionEstablished) {
return null;
}
// get mailboxStore object
MailboxStore mailboxStore = MailBoxStoreList.getMailStoreByMailBox(mailbox);
try {
// Open inbox folder to get messages metadata
srcFolderObj = mailboxStore.getStore().getFolder(srcFolder);
srcFolderObj.open(Folder.READ_WRITE);
// create search Term
SearchTerm term = new SearchTerm() {
private static final long serialVersionUID = 7L;
#Override
public boolean match(Message message) {
try {
String mailSubject = message.getSubject();
if (mailSubject == null) {
mailSubject = "";
}
if (mailSubject.equals(subject)) {
return true;
}
} catch (MessagingException ex) {
log.error("Failed to search for mail with mailbox: " + mailbox + " in folder: " + srcFolder
+ " subject: " + subject + " Error: " + ExceptionUtils.getStackTrace(ex));
}
return false;
}
};
// search for the relevant message
Message[] messages = srcFolderObj.search(term);
UIDFolder uf = (UIDFolder) srcFolderObj;
return String.valueOf(uf.getUID(messages[0]));
} catch (Exception e) {
log.error("Subject: Failed to find id of mail in mailbox " + mailbox + " in folder " + srcFolder
+ " , Error: " + ExceptionUtils.getStackTrace(e));
return null;
} finally {
try {
if (srcFolderObj != null && srcFolderObj.isOpen()) {
srcFolderObj.close();
}
} catch (Exception e) {
}
}
}
i also tried to replace SearchTerm override with the following but performance was the same:
SearchTerm searchTerm = new SubjectTerm(subject);
Thanks in advance!
I had been trying to detect faces from a video stored on Amazon S3, the faces have to be matched against the collection that has the faces which are to be searched for in the video.
I have used Amazon VideoDetect.
My piece of code, goes like this:
CreateCollection createCollection = new CreateCollection(collection);
createCollection.makeCollection();
AddFacesToCollection addFacesToCollection = new AddFacesToCollection(collection, bucketName, image);
addFacesToCollection.addFaces();
VideoDetect videoDetect = new VideoDetect(video, bucketName, collection);
videoDetect.CreateTopicandQueue();
try {
videoDetect.StartFaceSearchCollection(bucketName, video, collection);
if (videoDetect.GetSQSMessageSuccess())
videoDetect.GetFaceSearchCollectionResults();
} catch (Exception e) {
e.printStackTrace();
return false;
}
videoDetect.DeleteTopicandQueue();
return true;
The things seem to work fine till StartFaceSearchCollection and I am getting a jobId being made and a queue as well. But when it is trying to go around to get GetSQSMessageSuccess, its never returning me any message.
The code which is trying to fetch the message is :
ReceiveMessageRequest.Builder receiveMessageRequest = ReceiveMessageRequest.builder().queueUrl(sqsQueueUrl);
messages = sqs.receiveMessage(receiveMessageRequest.build()).messages();
Its having the correct sqsQueueUrl which exist. But I am not getting anything in the message.
On timeout its giving me this exception :
software.amazon.awssdk.core.exception.SdkClientException: Unable to execute HTTP request: sqs.region.amazonaws.com
at software.amazon.awssdk.core.exception.SdkClientException$BuilderImpl.build(SdkClientException.java:97)
Caused by: java.net.UnknownHostException: sqs.region.amazonaws.com
So is there any alternative to this, instead of SQSMessage, can we track/poll the jobId any other way ?? Or I am missing out on anything ??
The simple working code snippet to receive SQS message with the valid sqsQueueUrl for more
ReceiveMessageRequest receiveMessageRequest = new ReceiveMessageRequest(sqsQueueUrl);
final List<Message> messages = sqs.receiveMessage(receiveMessageRequest).getMessages();
for (final Message message : messages) {
System.out.println("Message");
System.out.println(" MessageId: " + message.getMessageId());
System.out.println(" ReceiptHandle: " + message.getReceiptHandle());
System.out.println(" MD5OfBody: " + message.getMD5OfBody());
System.out.println(" Body: " + message.getBody());
for (final Entry<String, String> entry : message.getAttributes().entrySet()) {
System.out.println("Attribute");
System.out.println(" Name: " + entry.getKey());
System.out.println(" Value: " + entry.getValue());
}
}
System.out.println();
I'm working on a web app (running on Tomcat) that calls programs on an IBM i (AS/400) using the JTOpen ProgramCall class (com.ibm.as400.access.ProgramCall). My problem is with program calls that take more than 30s to respond, which are triggering a java.net.SocketTimeoutException: Read timed out exception.
There is a setTimeout() method available for this class, but it doesn't seem to have an effect on the socket timeout. I've also checked my Tomcat configurations and didn't see anything that would cause this behavior.
Does anyone know of a way to alter the timeout for such an implementation?
Code:
pgmCall.setProgram(getCompleteName(), parmList);
initializeAS400TextParameters();
// Run the AS/400 program.
try {
Trace.setTraceDiagnosticOn(true);
Trace.setTraceInformationOn(true);
Trace.setTraceWarningOn(true);
Trace.setTraceErrorOn(true);
Trace.setTraceDatastreamOn(true);
if (pgmCall.run() != true) {
messageList = pgmCall.getMessageList();
for (int i = 0; i < messageList.length; i++) {
log.debug("Error Message " + i + " " + messageList[i]);
}
setCompletionMsg("Program call failed.");
log.debug("442 Program call failed.");
return false;
} else {
messageList = pgmCall.getMessageList();
for (int i = 0; i < messageList.length; i++) {
log.debug("Success Message " + i + " " + messageList[i]);
}
setCompletionMsg("Program called ok.");
log.debug("452 Program called ok.");
return true;
}
} catch (Exception e) {
// This is where the timeout exception is thrown
log.debug("Error Running Program: " + e.getMessage() + " " + e.getLocalizedMessage());
setCompletionMsg(e.getMessage());
}
Well, after several more hours I've found the solution. Apparently the original developer added a socket timeout parameter to the JDBC connection string - simply removing the parameter did the trick as the default value is 0, or infinite timeout.
Before:
String connectionStr = "jdbc:as400://" + systemInfo.getIPAddress() + ":1527" + ";naming=system;socket timeout=30000;thread used=false;errors=full;prompt=false;date format=iso;block size=128;transaction isolation=none;user=" + systemInfo.getUserName() + ";password=" + systemInfo.getPassword();
After:
String connectionStr = "jdbc:as400://" + systemInfo.getIPAddress() + ":1527" + ";naming=system;thread used=false;errors=full;prompt=false;date format=iso;block size=128;transaction isolation=none;user=" + systemInfo.getUserName() + ";password=" + systemInfo.getPassword();
:\
I'm busy writing a Program that Transmits GPS Coordinates to a Server from a mobile phone where the coordinates are then used for calculations. But I'm constantly hitting a wall with blackberry. I have built the Android App and it works great but can't seem to contact the server on a real blackberry device. I have tested the application in a simulator and it works perfectly but when I install it on a real phone I get no request the phone.
I have read quite a bit about the secret strings to append at the end of the url so I adapted some demo code to get me the first available transport but still nothing ...
The Application is Signed and I normally then either install it by debugging through eclipse or directly on the device from the .jad file and allow the application the required permissions.
The current code was adapted from the HTTP Connection Demo in the Blackberry SDK.
Could you have a look and give me some direction. I'm losing too much hair here ...
The Backend Service that keeps running:
public void run() {
System.out.println("Starting Loop");
Criteria cr = new Criteria();
cr.setHorizontalAccuracy(Criteria.NO_REQUIREMENT);
cr.setVerticalAccuracy(Criteria.NO_REQUIREMENT);
cr.setCostAllowed(false);
cr.setPreferredPowerConsumption(Criteria.NO_REQUIREMENT);
cr.setPreferredResponseTime(1000);
LocationProvider lp = null;
try {
lp = LocationProvider.getInstance(cr);
} catch (LocationException e) {
System.out.println("*****************Exception" + e);
}
if (lp == null) {
UiApplication.getUiApplication().invokeLater(new Runnable() {
public void run() {
Dialog.alert("GPS not supported!");
return;
}
});
} else {
System.out
.println(lp.getState() + "-" + LocationProvider.AVAILABLE);
switch (lp.getState()) {
case LocationProvider.AVAILABLE:
// System.out.println("Provider is AVAILABLE");
while (true) {
Location l = null;
int timeout = 120;
try {
l = lp.getLocation(timeout);
final Location fi = l;
System.out.println("Got a Coordinate "
+ l.getQualifiedCoordinates().getLatitude()
+ ", "
+ l.getQualifiedCoordinates().getLongitude());
System.out.println("http://" + Constants.website_base
+ "/apis/location?device_uid=" + Constants.uid
+ "&lat="
+ l.getQualifiedCoordinates().getLatitude()
+ "&lng="
+ l.getQualifiedCoordinates().getLongitude());
if (!_connectionThread.isStarted()) {
fetchPage("http://"
+ Constants.website_base
+ "/apis/location?device_uid="
+ Constants.uid
+ "&lat="
+ l.getQualifiedCoordinates().getLatitude()
+ "&lng="
+ l.getQualifiedCoordinates()
.getLongitude());
} else {
createNewFetch("http://"
+ Constants.website_base
+ "/apis/location?device_uid="
+ Constants.uid
+ "&lat="
+ l.getQualifiedCoordinates().getLatitude()
+ "&lng="
+ l.getQualifiedCoordinates()
.getLongitude());
}
Thread.sleep(1000 * 60);
} catch (LocationException e) {
System.out.println("Location timeout");
} catch (InterruptedException e) {
System.out.println("InterruptedException"
+ e.getMessage());
} catch (Exception ex) {
System.err.println(ex.getMessage());
ex.printStackTrace();
}
}
}
}
My Connection is Made with:
ConnectionFactory connFact = new ConnectionFactory();
ConnectionDescriptor connDesc = connFact.getConnection(getUrl());
// Open the connection and extract the data.
try {
// StreamConnection s = null;
// s = (StreamConnection) Connector.open(getUrl());
HttpConnection httpConn = (HttpConnection) connDesc.getConnection();
/* Data is Read here with a Input Stream */
Any Ideas ?
Figured it out!
Using a function I found online to determine which ; extension to use when connecting by using numerous Try / Catch. Then had to set the Internet APN settings. I'm in South-Africa using Vodacom so the APN is "Internet" with no Password.
Barely have hair left ....
My android program isn't working. I am using normal client-server sockets. I have tested my server with telnet and it works fine, but when I try it with my android program, it doesn't work (more details in a second). Here's my code:
Socket s = null;
try
{
String SocketServerAddress = db.getPhSsServerAddress();
Integer SocketServerPort = db.getPhSsServerPort();
s = new Socket(SocketServerAddress, SocketServerPort);
Log.d(MY_DEBUG_TAG, "Setting up Socket: " + SocketServerAddress + ":" + SocketServerPort);
DataOutputStream out = new DataOutputStream(s.getOutputStream());
DataInputStream in = new DataInputStream(s.getInputStream());
Log.d(MY_DEBUG_TAG, "Connected to: " + s.getInetAddress() + " on port " + s.getPort());
out.writeUTF("Helo, Server");
out.flush();
Log.d(MY_DEBUG_TAG, "Bytes written: " + out.size());
String st = in.readUTF();
Log.d(MY_DEBUG_TAG, "SocketServerResponse: " + st);
}
catch (UnknownHostException e)
{
Log.e(MY_ERROR_TAG, "UnknownHostException: " + e.getMessage() + "; " + e.getCause());
}
catch (IOException e)
{
Log.e(MY_ERROR_TAG, "IOException: " + e.getMessage() + "; " + e.getCause() + "; " + e.getLocalizedMessage());
}
finally
{
try {
s.close();
} catch (IOException e) {
Log.e(MY_ERROR_TAG, "IOException on socket.close(): " + e.getMessage() + "; " + e.getCause());
}
}
All I ever get here is a thrown IOException with no message or cause attached. The specific line causing the error is the String st = in.readUTF(). If I comment out that line, my code runs fine (no exceptions thrown), but my server does not acknowledge that any data has been sent to it. And of course I don't get any data back since that line is commented out.
So, how can I figure out what the problem is? Tonight I am going to try and see what is being passed with wireshark to see if that gives any insight.
Is the server using readUTF() and writeUTF() too? writeUTF() writes data in a unique format that can only be understood by readUTF(), which won't understand anything else.
EDIT EOFException means that there is no more data. You should catch it separately and handle it by closing the socket etc. It can certainly be caused spuriously by readUTF() trying to read data that wasn't written with writeUTF().
And deciding it was an IOException when it was really an EOFException means you didn't print out or log the exception itself, just its message. Always use the log methods provided for exceptions, or at least use Exception.toString().
As I remember I had a problem with DataInpuStream some day... try doing so:
in = new DataInputStream(new BufferedInputStream(socket.getInputStream()));