I'm creating an application that uses web view to load the website and allow to download data like IMG/PDF/GIF. The problem is that the download link is not a normal link it's blob:.
I know blob: URL does not refer to the data that exists on the server, it refers to data that your browser currently has in memory.
class DownloadBlobFileJSInterface {
private Context mContext;
private DownloadGifSuccessListener mDownloadGifSuccessListener;
public DownloadBlobFileJSInterface(Context context) {
this.mContext = context;
}
public static String getBase64StringFromBlobUrl(String blobUrl) {
if (blobUrl.startsWith("blob")) {
return "javascript: var xhr = new XMLHttpRequest();" +
"xhr.open('GET', '" + blobUrl + "', true);" +
"xhr.setRequestHeader('Content-type','image/gif');" +
"xhr.responseType = 'blob';" +
"xhr.onload = function(e) {" +
" if (this.status == 200) {" +
" var blobFile = this.response;" +
" var reader = new FileReader();" +
" reader.readAsDataURL(blobFile);" +
" reader.onloadend = function() {" +
" base64data = reader.result;" +
" Android.getBase64FromBlobData(base64data);" +
" }" +
" }" +
"};" +
"xhr.send();";
}
return "javascript: console.log('It is not a Blob URL');";
}
public void setDownloadGifSuccessListener(DownloadGifSuccessListener listener) {
mDownloadGifSuccessListener = listener;
}
#JavascriptInterface
public void getBase64FromBlobData(String base64Data) {
convertToGifAndProcess(base64Data);
}
private void convertToGifAndProcess(String base64) {
ContextWrapper wrapper = new ContextWrapper(mContext);
String fullPath =wrapper.getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS).toString();
File gifFile = new File(fullPath+ "/File_" + System.currentTimeMillis() + "_.gif");
saveGifToPath(base64, gifFile);
Toast.makeText(mContext, "Downloaded", Toast.LENGTH_SHORT).show();
if (mDownloadGifSuccessListener != null) {
mDownloadGifSuccessListener.downloadGifSuccess(gifFile.getAbsolutePath());
}
}
private void saveGifToPath(String base64, File gifFilePath) {
try {
byte[] fileBytes = Base64.decode(base64.replaceFirst(
"data:image/gif;base64,", ""), 0);
FileOutputStream os = new FileOutputStream(gifFilePath, false);
os.write(fileBytes);
os.flush();
os.close();
} catch (Exception e) {
e.printStackTrace();
}
}
public interface DownloadGifSuccessListener {
void downloadGifSuccess(String absolutePath);
}
}
I want to download the file in device storage.
Is there any way to get data from the blob: URL?
Or
Is it possible to send that data to chrome to download.
I know there is a lot of questions out there like this, this on StackOverflow, I almost tried all but didn't find any of these working.
Please note that i am writing a java program using tes4j and i am able to extract the tiff file and save it as pdf but many times i am getting this error. I am running the files as a batch using callable i am taking 5 files and process them during which i get this error. test4j i am using as a maeven dependency.
Error Description
java.util.concurrent.ExecutionException: java.lang.Error: Invalid memory access
at java.util.concurrent.FutureTask.report(Unknown Source)
at java.util.concurrent.FutureTask.get(Unknown Source)
at com.mkyong.listener.SerachablePDFConversionService.processAllFiles(SerachablePDFConversionService.java:197)
at com.mkyong.listener.SerachablePDFConversionService.run(SerachablePDFConversionService.java:107)
at java.lang.Thread.run(Unknown Source)
Caused by: java.lang.Error: Invalid memory access
at com.sun.jna.Native.invokeInt(Native Method)
at com.sun.jna.Function.invoke(Function.java:419)
at com.sun.jna.Function.invoke(Function.java:354)
at com.sun.jna.Library$Handler.invoke(Library.java:244)
at com.sun.proxy.$Proxy0.gsapi_init_with_args(Unknown Source)
at org.ghost4j.Ghostscript.initialize(Ghostscript.java:350)
at com.mkyong.listener.SerachablePDFConversionService.convertPDFToTiff(SerachablePDFConversionService.java:137)
at com.mkyong.listener.SerachablePDFConversionService$1.call(SerachablePDFConversionService.java:213)
at com.mkyong.listener.SerachablePDFConversionService$1.call(SerachablePDFConversionService.java:1)
at java.util.concurrent.FutureTask.run(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
Code
package com.apache.pdfbox.ocr.tesseract;
import java.io.File;
import java.nio.file.FileSystems;
import java.nio.file.Files;
import java.nio.file.StandardCopyOption;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import org.ghost4j.Ghostscript;
import org.ghost4j.GhostscriptException;
import net.sourceforge.tess4j.ITesseract;
import net.sourceforge.tess4j.ITesseract.RenderedFormat;
import net.sourceforge.tess4j.Tesseract;
import net.sourceforge.tess4j.TesseractException;
public class SerachablePDFConversionService {
private static final String OCR_INPUT_FOLDER = System.getenv("OCR_INPUT");
private static final String OCR_OUTPUT_FOLDER = System.getenv("OCR_OUTPUT");
private static final String OCR_SUCCESS_FOLDER = System.getenv("OCR_SUCCESS");
private static final String TESSDATA_PREFIX = System.getenv("TESSDATA_PREFIX");
public static void main(String[] args) {
File inputFiles[] = new File(OCR_INPUT_FOLDER).listFiles();
String tiffFileName = "";
String inputFileName = "";
try {
for (File inputFile : inputFiles) {
inputFileName = inputFile.getName();
System.out.println("Input File Name is [" + inputFileName + "]");
if (inputFileName != null && inputFileName.length() > 0
&& inputFileName.toLowerCase().indexOf(".pdf") > 0) {
tiffFileName = inputFile.getName().replaceAll(".pdf", ".tif").replaceAll(".PDF", ".tif");
System.out.println("Tiff File Name is [" + tiffFileName + "]");
System.out.println("Start Time" + new Date());
if (SerachablePDFConversionService.convertPDFToTiff(inputFileName, tiffFileName).equals("true")) {
System.out.println("PDF to tiff conversion is successful");
if (SerachablePDFConversionService.doOCR(inputFileName, tiffFileName).equals("true")) {
System.out.println("Searchable PDF creation is successful");
Files.move(
FileSystems.getDefault()
.getPath(OCR_OUTPUT_FOLDER + File.separator + inputFileName),
FileSystems.getDefault()
.getPath(OCR_SUCCESS_FOLDER + File.separator + inputFileName),
StandardCopyOption.REPLACE_EXISTING);
System.out.println("End Time" + new Date());
} else {
System.out.println("Searchable PDF creation is failed");
}
} else {
System.out.println("PDF to tiff conversion is failed");
}
} else {
}
}
} catch (Exception e) {
System.out.println("ERROR in Main Method: " + e.getMessage());
System.err.println(e.getMessage());
}
}
public static String covertToTiffAndOCR(ArrayList<String> inputFiles) throws Exception {
String success = "false";
for (String inputFileName : inputFiles) {
System.out.println("File Name " + inputFileName);
String tiffFileName = "";
if (inputFileName != null && inputFileName.length() > 0
&& inputFileName.toLowerCase().indexOf(".pdf") > 0) {
tiffFileName = inputFileName.replaceAll(".pdf", ".tif").replaceAll(".PDF", ".tif");
System.out.println("Tiff File Name is [" + tiffFileName + "]");
if (SerachablePDFConversionService.convertPDFToTiff(inputFileName, tiffFileName).equals("true")) {
System.out.println("PDF to tiff conversion is successful");
if (SerachablePDFConversionService.doOCR(inputFileName, tiffFileName).equals("true")) {
System.out.println("Searchable PDF creation is successful");
Files.move(FileSystems.getDefault().getPath(OCR_OUTPUT_FOLDER + File.separator + inputFileName),
FileSystems.getDefault().getPath(OCR_SUCCESS_FOLDER + File.separator + inputFileName),
StandardCopyOption.REPLACE_EXISTING);
} else {
System.out.println("Searchable PDF creation is failed");
}
} else {
System.out.println("PDF to tiff conversion is failed");
}
} else {
}
}
success = "true";
return success;
}
public static String convertPDFToTiff(String pdfFile, String tiffFile) {
System.out.println("Called=========convertPDFToTiff " + pdfFile + "tiffFile " + tiffFile);
String opSuccess = "false";
Ghostscript gs = Ghostscript.getInstance();
try {
synchronized (gs) {
String[] gsArgs = new String[9];
gsArgs[0] = "-gswin64";
gsArgs[1] = "-q";
gsArgs[2] = "-r300x300";
gsArgs[3] = "-dNOPAUSE";
gsArgs[4] = "-dBATCH";
// gsArgs[5] = "-sDEVICE=tiffg4";
// gsArgs[5] = "-sDEVICE=tiffgray";
gsArgs[5] = "-sDEVICE=tiff24nc";
gsArgs[6] = "-sCompression=lzw";
gsArgs[7] = "-sOutputFile=" + OCR_OUTPUT_FOLDER + File.separator + tiffFile;
gsArgs[8] = OCR_INPUT_FOLDER + File.separator + pdfFile;
// execute and exit interpreter
gs.initialize(gsArgs);
gs.exit();
opSuccess = "true";
}
} catch (GhostscriptException e) {
opSuccess = "false";
System.out.println("ERROR: " + e.getMessage());
} catch (Exception e) {
opSuccess = "false";
System.out.println("ERROR: " + e.getMessage());
} finally {
try {
Ghostscript.deleteInstance();
} catch (GhostscriptException e) {
opSuccess = "false";
System.out.println("ERROR: " + e.getMessage());
}
}
return opSuccess;
}
public synchronized static String doOCR(String pdfFile, String tiffFile) {
System.out.println("Called======doOCR " + pdfFile + " tiffFile " + tiffFile);
String opSuccess = "false";
ITesseract instance = new Tesseract();
List<RenderedFormat> formats = new ArrayList<RenderedFormat>();
formats.add(RenderedFormat.PDF);
try {
instance.setDatapath(TESSDATA_PREFIX);
instance.setLanguage("eng+ara");
instance.setOcrEngineMode(1);
instance.setPageSegMode(3);
instance.createDocuments(OCR_OUTPUT_FOLDER + File.separator + tiffFile,
OCR_OUTPUT_FOLDER + File.separator + pdfFile.replaceAll(".pdf", "").replaceAll(".PDF", ""),
formats);
opSuccess = "true";
} catch (TesseractException e) {
opSuccess = "false";
System.out.println("OCR ERROR: " + e.getMessage());
System.err.println(e.getMessage());
} catch (Exception e) {
opSuccess = "false";
System.out.println("OCR ERROR: " + e.getMessage());
System.err.println(e.getMessage());
}
return opSuccess;
}
public void processAllFiles(ArrayList<String> ipFiles) throws Exception {
java.util.List<Callable<String>> tasks = new ArrayList<Callable<String>>(ipFiles.size());
for (String ipFileName : ipFiles) {
System.out.println("11111111" + ipFileName);
tasks.add(processPartTask1(ipFileName));
}
ExecutorService es = Executors.newFixedThreadPool(ipFiles.size());
java.util.List<Future<String>> results = es.invokeAll(tasks);
for (Future<String> result : results)
System.out.println(result.get());
es.shutdown();
}
public Callable<String> processPartTask1(String ipFileName) {
return new Callable<String>() {
public String call() throws Exception {
System.out.println("22222222" + ipFileName);
String tiffFileName = "";
String inputFileName = ipFileName;
String returnvalue = "false";
if (inputFileName != null && inputFileName.length() > 0
&& inputFileName.toLowerCase().indexOf(".pdf") > 0) {
tiffFileName = ipFileName.replaceAll(".pdf", ".tif").replaceAll(".PDF", ".tif");
}
if (SerachablePDFConversionService.convertPDFToTiff(inputFileName, tiffFileName).equals("true")) {
System.out.println("PDF to tiff conversion is successful");
if (SerachablePDFConversionService.doOCR(inputFileName, tiffFileName).equals("true")) {
System.out.println("Searchable PDF creation is successful");
Files.move(FileSystems.getDefault().getPath(OCR_OUTPUT_FOLDER + File.separator + inputFileName),
FileSystems.getDefault().getPath(OCR_SUCCESS_FOLDER + File.separator + inputFileName),
StandardCopyOption.REPLACE_EXISTING);
System.out.println("End Time" + new Date());
returnvalue = "true " + inputFileName;
} else {
System.out.println("Searchable PDF creation is failed");
}
}
return returnvalue;// this needs to be changed
}
};
}
public void processPDFFiles() throws Exception {
File inputFiles[] = new File(OCR_INPUT_FOLDER).listFiles();
String inputFileName = "";
ArrayList<String> files = new ArrayList<String>();
try {
for (File inputFile : inputFiles) {
inputFileName = inputFile.getName();
files.add(inputFileName);
}
} catch (Exception e) {
}
SerachablePDFConversionService serachablePDFConversionService = new SerachablePDFConversionService();
serachablePDFConversionService.processAllFiles(files);
}
}
I am seeing the following error in logs from last week:
<Feb 7> <Warning> <WLW> <000000> <Id=top-level; Method=processes.FTPInboundProcess.subscription(); Failure=com.bea.wli.bpm.runtime.UnhandledProcessException: Unhandled process exception [ServiceException]>
<Feb 7> <Info> <EJB> <BEA-010213> <Message-Driven EJB: AsyncDispatcher's transaction was rolledback. The transaction details are: Xid=BEA1-3C63D2E9CC47D571774C(183265728),Status=Rolled back.
The code is below:
FTPInboundProcess.jpd
package processes;
import com.bea.data.RawData;
import com.bea.jpd.JpdContext;
import com.bea.jpd.JpdContext.ExceptionInfo;
import com.bea.jpd.ProcessDefinition;
import com.bea.wli.eventGenerator.FileEventGeneratorDocument;
import com.bea.wli.eventGenerator.TimerEventGeneratorDocument;
import com.bea.xml.XmlObject;
import com.bea.xml.XmlTokenSource;
import com.integration.exception.AppException;
import com.integration.util.EnvProperties;
import com.integration.util.KeyGenerator;
import com.integration.util.LogParameters;
import com.integration.util.MessageDataOperation;
import com.integration.util.PASLevel;
import com.integration.util.PASLogger;
import com.integration.util.StringEncrypter;
import com.integration.util.Utility;
import java.io.ByteArrayOutputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
import java.util.logging.Logger;
import ftp.InterfaceDocument.Interface;
import ftp.InterfacesDocument;
import ftp.InterfacesDocument.Factory;
import ftp.InterfacesDocument.Interfaces;
import inbound.IFileAdapter;
import inbound.impl.FTPClientImpl;
import inbound.impl.FileClientImpl;
import inbound.impl.SFTPClientImpl;
import outbound.PostProcess;
public class FTPInboundProcess
implements ProcessDefinition
{
public boolean bIsFtpDeleteSuccess;
public boolean isWriteToLocalDirSuccess;
public String fileArchiveDir;
public boolean isChDirSuccess;
public byte[] ftpData;
public boolean isPutSuccess;
public TimerEventGeneratorDocument timerEventGeneratorDoc;
public FileEventGeneratorDocument fileEventGeneratorDoc;
public RawData inputRawData;
public IFileAdapter ftp;
public static String PROCESS_NAME = "FileXFRI";
public String processLabel;
public long processStartTime;
public long originalStartTime;
public long processId;
public long parentProcessId;
public String key;
public String protocol;
public String documentKey;
public boolean bAppException;
public boolean bMesageInorder;
public boolean bNewMessage;
public String errorStr;
public String sftpkey;
public String fileName;
public int fileCounter;
public String emailUser;
public transient Logger logger;
static final long serialVersionUID = 1L;
public FTPInboundProcess.Callback callback;
public String ftpHostName;
public int ftpPort;
public String ftpUserName;
public String ftpPassword;
public String ftpDir;
public String ftpArchDir;
public String ftpLocalDir;
public String filePattern;
public String isFtpPostActionDeleteRequired;
public String isFtpPostActionArchiveRequired;
public String isEncryptRequired;
public long fileSize;
public String interfaceId;
public String emailYN;
public HashMap dataMap;
public XmlObject inputXML;
public String[] listOfFTPFiles;
public boolean isFTPConnected;
JpdContext context;
int postProcessReturnvalue;
public void subscription(XmlObject x0, TimerEventGeneratorDocument x1)
{
this.inputXML = x0;
this.timerEventGeneratorDoc = x1;
}
void initProcessVariables()
{
this.processStartTime = System.currentTimeMillis();
this.processLabel = "";
this.processId = 0L;
this.postProcessReturnvalue = 0;
this.parentProcessId = 0L;
this.documentKey = "";
this.bAppException = false;
this.errorStr = "";
this.fileSize = 0L;
this.interfaceId = "";
this.emailYN = "";
this.emailUser = "";
this.dataMap = new HashMap();
}
public void init()
throws Exception
{
try
{
this.logger = PASLogger.getLogger("PAS." + PROCESS_NAME);
this.logger.log(PASLevel.FINER, "Timer InputXML :" + this.inputXML.xmlText());
this.logger.log(PASLevel.FINER, "Type::" + this.inputXML.getClass());
initProcessVariables();
String xmlText = this.inputXML.xmlText();
this.logger.log(PASLevel.FINER, "INPUT::" + xmlText);
InterfacesDocument input = InterfacesDocument.Factory.parse(xmlText);
this.interfaceId = input.getInterfaces().getInterfaceArray()[0].getId();
this.logger.log(PASLevel.FINER, "Interface id : " + ((InterfacesDocument)this.inputXML).getInterfaces().getInterfaceArray(0).getId());
this.processId = KeyGenerator.generateKey("PROCESS_ID");
this.documentKey = (PROCESS_NAME + "::FTP::" + this.interfaceId + "::" + this.processId);
this.key = (PROCESS_NAME + "::FTP::" + this.interfaceId + "::" + this.processId);
this.logger.log(PASLevel.FINER, "Parsing Input Document End:" + System.currentTimeMillis());
this.processLabel = ("Key=" + this.key + ",ProcessId=" + this.processId + ",InterfaceId=" + this.interfaceId);
this.processStartTime = System.currentTimeMillis();
MessageDataOperation.insertMessageData(this.processId, this.documentKey, PROCESS_NAME, this.key, this.processStartTime, this.parentProcessId);
updateProcessLabel(this.processLabel);
this.protocol = EnvProperties.getProperty(PROCESS_NAME + "." + this.interfaceId + ".PROTOCOL");
this.ftpHostName = EnvProperties.getProperty(PROCESS_NAME + "." + this.interfaceId + ".FTPHOST");
this.logger.log(PASLevel.FINEST, " ftpHostName :" + this.ftpHostName);
try
{
this.ftpPort = Integer.parseInt(EnvProperties.getProperty(PROCESS_NAME + "." + this.interfaceId + ".PORT"));
}
catch (Exception e)
{
this.logger.log(PASLevel.WARNING, "FTP Port not defined for the Interface :" + this.interfaceId + " .... using default port");
this.ftpPort = 21;
}
this.logger.log(PASLevel.FINE, " ftpPort :" + this.ftpPort);
this.sftpkey = Utility.nullToStr(EnvProperties.getProperty(PROCESS_NAME + "." + this.interfaceId + ".SFTPKEY"));
this.logger.log(PASLevel.FINE, " SFTPKEY :" + this.sftpkey);
this.dataMap.put("SFTPKEY", this.sftpkey);
this.ftpUserName = EnvProperties.getProperty(PROCESS_NAME + "." + this.interfaceId + ".FTPUSER");
this.logger.log(PASLevel.FINE, " ftpUserName :" + this.ftpUserName);
this.ftpPassword = EnvProperties.getProperty(PROCESS_NAME + "." + this.interfaceId + ".FTPPASSWORD");
this.logger.log(PASLevel.FINE, " ftpPassword :" + this.ftpPassword);
this.filePattern = EnvProperties.getProperty(PROCESS_NAME + "." + this.interfaceId + ".FILEPATTERN");
this.logger.log(PASLevel.FINE, " filePattern :" + this.filePattern);
this.ftpArchDir = EnvProperties.getProperty(PROCESS_NAME + "." + this.interfaceId + ".FTPARCH");
this.logger.log(PASLevel.FINE, " ftpArchDir :" + this.ftpArchDir);
this.ftpDir = Utility.nullToStr(EnvProperties.getProperty(PROCESS_NAME + "." + this.interfaceId + ".FTPDIR"));
this.ftpLocalDir = EnvProperties.getProperty(PROCESS_NAME + "." + this.interfaceId + ".FTPLOCALDIR");
this.fileArchiveDir = EnvProperties.getProperty(PROCESS_NAME + "." + this.interfaceId + ".FILEARCHIVEDIR");
this.isFtpPostActionDeleteRequired = EnvProperties.getProperty(PROCESS_NAME + "." + this.interfaceId + ".FTPPOSTDELETE");
this.isEncryptRequired = EnvProperties.getProperty(PROCESS_NAME + "." + this.interfaceId + ".ENCRYPT");
this.isFtpPostActionArchiveRequired = EnvProperties.getProperty(PROCESS_NAME + "." + this.interfaceId + ".FTPPOSTARCHIVE");
this.logger.log(PASLevel.FINE, " ftpLocalDir :" + this.ftpLocalDir);
this.logger.log(PASLevel.FINE, " isFtpPostActionArchiveRequired :" + this.isFtpPostActionArchiveRequired);
this.logger.log(PASLevel.FINE, " isFtpPostActionDeleteRequired :" + this.isFtpPostActionDeleteRequired);
return;
}
catch (Exception e)
{
e.printStackTrace();
this.logger.log(PASLevel.SYSTEM_ERROR, e.getMessage(), new LogParameters(this.processId, PROCESS_NAME, this.processLabel, e));
throw e;
}
}
void updateProcessLabel(String label)
{
this.context.setProcessLabel(this.processLabel);
}
public boolean isAppException()
{
return this.bAppException;
}
public boolean isMessageInorder()
{
return this.bMesageInorder;
}
String getErrorEmailUser(Object[] args)
throws Exception
{
try
{
if ((args == null) || (args.length == 0)) {
return "";
}
this.emailUser = EnvProperties.getProperty(PROCESS_NAME + "." + this.interfaceId + ".EMAIL_USER");
return this.emailUser;
}
catch (Exception e)
{
this.logger.log(PASLevel.SYSTEM_ERROR, "ProcessLabel:" + this.processLabel + ":Error:" + e.getMessage(), new LogParameters(this.processId, PROCESS_NAME, this.processLabel, e));
}
return "";
}
public void context_onInitialMessageFailure(String methodName, Object[] args)
throws Exception
{
try
{
this.processId = Utility.context_onInitialMessageFailure(PROCESS_NAME, args, this.logger);
String body = "Due to the error the interface file could not be sent. \n";
body = body + "System will retry the file after sometime.";
this.errorStr = "";
sendErrorEmail(body, getErrorEmailUser(args));
return;
}
catch (Exception e)
{
this.logger.log(PASLevel.SYSTEM_ERROR, "ProcessLabel:" + this.processLabel + ":Error:" + e.getMessage(), new LogParameters(this.processId, PROCESS_NAME, this.processLabel, e));
throw e;
}
}
public void globalExceptionHandler()
throws Exception
{
Exception e = null;
try
{
e = this.context.getExceptionInfo().getException();
this.errorStr = e.getMessage();
}
catch (Throwable localThrowable) {}
this.bAppException = Utility.globalExceptionHandler(e, this.logger, PROCESS_NAME, this.processId, this.parentProcessId, "", this.inputRawData.byteValue(), "xml", true);
if (this.bAppException) {
this.processLabel = (this.processLabel + ",AppException , " + e.getClass());
} else {
this.processLabel = (this.processLabel + ",SystemException , " + e.getClass());
}
updateProcessLabel(this.processLabel);
this.logger.log(PASLevel.INFO, "Exception Raised in Process , Process Label:" + this.processLabel);
}
public void systemExceptionProcessing()
throws Exception
{}
public void sendDataErrorEmail()
throws Exception
{
String body = "Due to the error the file could not sent \n\n\n";
body = body + ",Filename=" + this.fileName;
this.emailUser = EnvProperties.getProperty(PROCESS_NAME + "." + this.interfaceId + ".EMAIL_USER");
sendErrorEmail(body, this.emailUser);
}
public void sendErrorEmail(String body, String to)
throws Exception
{
String subject = "";
String cc = "";
String bcc = "";
HashMap map = new HashMap();
try
{
body = body + this.errorStr;
subject = "Due to the error the interface file could not be sent. " + this.key;
if ((to == null) || (to.equals(""))) {
to = Utility.getErrorEmail();
}
Utility.sendEmail(PROCESS_NAME, this.processId, "Business", body, subject, to, "", cc, bcc, "");
return;
}
catch (Exception e)
{
this.logger.log(PASLevel.SYSTEM_ERROR, "ProcessLabel:" + this.processLabel + ":Error:" + e.getMessage(), new LogParameters(this.processId, PROCESS_NAME, this.processLabel, e));
throw e;
}
}
public boolean isMessageInorder1()
{
return this.bMesageInorder;
}
public void handleAppException()
throws Exception
{}
public void cleanup()
throws Exception
{
this.inputRawData = null;
}
public void setFilesCount()
throws Exception
{
this.fileCounter = 0;
}
public void decrementFileCount()
throws Exception
{
this.fileCounter += 1;
}
public boolean checkFileCounterCondition()
{
return this.fileCounter < this.listOfFTPFiles.length;
}
public void raiseFTPConnectionException()
throws Exception
{
Exception e = new Exception("Error: FTP Connection Failure");
this.logger.log(PASLevel.SYSTEM_ERROR, ":ProcessLabel:" + this.processLabel + ":Error: FTP Connection Failure", new LogParameters(this.processId, PROCESS_NAME, this.processLabel, e));
throw e;
}
public boolean isFTPConnected()
{
return this.ftp.isConnected();
}
public boolean checkNoOfFilesReceived()
{
if ((this.listOfFTPFiles != null) && (this.listOfFTPFiles.length > 0)) {
return true;
}
return false;
}
public void sendEmail()
throws Exception
{
String subject = "";
String to = "";
String cc = "";
String bcc = "";
String body = "";
HashMap map = new HashMap();
try
{
this.emailYN = EnvProperties.getProperty(PROCESS_NAME + "." + this.interfaceId + ".EMAIL_YN");
if ((this.emailYN != null) && (!this.emailYN.equals("Y"))) {
return;
}
this.emailUser = EnvProperties.getProperty(PROCESS_NAME + "." + this.interfaceId + ".EMAIL_USER");
body = "Interface has processed the following file succesfully. :Filename:" + this.fileName;
to = this.emailUser;
subject = "Interface has sent the following file succesfully. Key::" + this.key + ":Filename:" + this.fileName;
if ((to == null) || (to.equals("")))
{
this.logger.log(PASLevel.WARNING, "ProcessLabel:" + this.processLabel + ":Error:" + "Email Receipent not specified.", new LogParameters(this.processId, PROCESS_NAME, this.processLabel, null));
to = Utility.getErrorEmail();
}
this.logger.log(PASLevel.FINE, "SCPExtract ... Sending an Email");
Utility.sendEmail(PROCESS_NAME, this.processId, "Business", body, subject, to, "", cc, bcc, "");
return;
}
catch (Exception e)
{
this.logger.log(PASLevel.SYSTEM_ERROR, "ProcessLabel:" + this.processLabel + ":Error:" + e.getMessage(), new LogParameters(this.processId, PROCESS_NAME, this.processLabel, e));
throw e;
}
}
public void createFTPClient()
throws Exception
{
if (this.protocol.equalsIgnoreCase("SFTP"))
{
this.ftp = new SFTPClientImpl();return;
}
if (this.protocol.equalsIgnoreCase("FTP"))
{
this.ftp = new FTPClientImpl();return;
}
this.ftp = new FileClientImpl();
}
public void connect()
throws Exception
{
try
{
if (((this.protocol.equals("FTP")) || (this.protocol.equals("SFTP"))) && ((this.ftpUserName == null) || (this.ftpPassword == null) || (this.ftpHostName == null)))
{
Exception e = new Exception("ftpUserName = null || this.ftpPassword = null || ftpHostName = null");
this.logger.log(PASLevel.SYSTEM_ERROR, e.getMessage(), new LogParameters(this.processId, PROCESS_NAME, this.processLabel, e));
throw e;
}
this.logger.log(PASLevel.FINE, "Connecting to the server .... :" + this.ftpHostName);
this.logger.log(PASLevel.FINE, "Host:" + this.ftpHostName + ":User:" + this.ftpUserName + ":Password:" + this.ftpPassword);
this.ftp.connect(this.ftpHostName, this.ftpPort, this.ftpUserName, this.ftpPassword, this.dataMap);
this.logger.log(PASLevel.FINE, "Connected to the server:" + this.ftpHostName);
return;
}
catch (Exception e)
{
this.logger.log(PASLevel.SYSTEM_ERROR, "ProcessLabel:" + this.processLabel + ":Error:" + e.getMessage(), new LogParameters(this.processId, PROCESS_NAME, this.processLabel, e));
throw e;
}
}
public void getRemoteFilesList()
throws Exception
{
try
{
this.logger.log(PASLevel.FINE, "Retriving List of Files .... :FtpDir:" + this.ftpDir);
this.logger.log(PASLevel.FINE, "File Pattern .... ::" + this.filePattern);
if (!this.ftpLocalDir.equals("")) {
this.ftp.setLocalDir(this.ftpLocalDir);
}
if (!this.ftpDir.equals("")) {
this.ftp.changeWorkingDirectory(this.ftpDir);
}
ArrayList list = this.ftp.listFiles(this.filePattern);
this.listOfFTPFiles = new String[list.size()];
System.arraycopy(list.toArray(), 0, this.listOfFTPFiles, 0, list.size());
for (int ind = 0; ind < this.listOfFTPFiles.length; ind++) {
this.logger.log(PASLevel.FINE, "List of Files:" + this.listOfFTPFiles[ind]);
}
return;
}
catch (Exception e)
{
this.logger.log(PASLevel.SYSTEM_ERROR, "ProcessLabel:" + this.processLabel + ":Error:" + e.getMessage(), new LogParameters(this.processId, PROCESS_NAME, this.processLabel, e));
e.printStackTrace();
throw e;
}
}
public void disconnect()
throws Exception
{
this.logger.log(PASLevel.FINE, "Zero input files ..... Disconnecting ...");
this.ftp.disconnect();
}
public void getFile()
throws Exception
{
try
{
this.fileName = this.listOfFTPFiles[this.fileCounter];
if (this.fileName == null) {
throw new Exception(" FTP fileName is null");
}
ByteArrayOutputStream getFileByteArrayOutputStream = this.ftp.getFile(this.fileName);
this.ftpData = getFileByteArrayOutputStream.toByteArray();
this.logger.log(PASLevel.FINE, "Got File Data ...");
return;
}
catch (Exception e)
{
this.logger.log(PASLevel.SYSTEM_ERROR, ":ProcessLabel:" + this.processLabel + ":Error:" + e.getMessage(), new LogParameters(this.processId, PROCESS_NAME, this.processLabel, e));
throw e;
}
}
public void backup()
throws Exception
{
try
{
String archiveYN = EnvProperties.getProperty(PROCESS_NAME + "." + this.interfaceId + ".LOCALARCHIVE");
String asciiYN = EnvProperties.getProperty(PROCESS_NAME + "." + this.interfaceId + ".ASCII_YN");
if (archiveYN.equals("Y"))
{
byte[] fileArchData;
if ((asciiYN.equals("Y")) && (this.isEncryptRequired.equals("Y")))
{
StringEncrypter encrypter = new StringEncrypter();
fileArchData = encrypter.encrypt(new String(this.ftpData)).getBytes();
}
else
{
fileArchData = this.ftpData;
}
Utility.createFile(this.fileArchiveDir + "/" + this.interfaceId + "_" + this.processId + "_" + this.fileName, fileArchData);
}
this.logger.log(PASLevel.FINE, "File Archieved ...::" + archiveYN + "::EncryptionYN::" + this.isEncryptRequired);
return;
}
catch (Exception e)
{
this.logger.log(PASLevel.SYSTEM_ERROR, ":ProcessLabel:" + this.processLabel + ":Error:" + e.getMessage(), new LogParameters(this.processId, PROCESS_NAME, this.processLabel, e));
throw e;
}
}
public void disconnect1()
throws Exception
{
try
{
this.ftp.disconnect();
return;
}
catch (Throwable localThrowable) {}
}
public void disconnect2()
throws Exception
{
try
{
this.ftp.disconnect();
return;
}
catch (Throwable localThrowable) {}
}
public void doPostProcess()
throws Exception
{
try
{
String sapPostProcessClass = EnvProperties.getProperty(PROCESS_NAME + "." + this.interfaceId + ".POSTPROCESS");
sapPostProcessClass = "washpost.pas.outbound.impl." + sapPostProcessClass;
Map fileMap = new HashMap();
this.logger.log(PASLevel.FINE, "PostProcess ::" + sapPostProcessClass);
if (!sapPostProcessClass.equals(""))
{
Class c = Class.forName(sapPostProcessClass);
PostProcess postProcess = (PostProcess)c.newInstance();
String passByRefFlag = EnvProperties.getProperty(PROCESS_NAME + "." + this.interfaceId + ".REFERENCE_YN");
byte[] tempFtpData = this.ftpData;
if ((passByRefFlag != null) && (passByRefFlag.equalsIgnoreCase("Y")))
{
String localDir = EnvProperties.getProperty(PROCESS_NAME + "." + this.interfaceId + ".LOCALDIR");
String localFileName = localDir + System.getProperty("file.separator") + this.fileName;
Utility.createFile(localFileName, this.ftpData);
tempFtpData = new byte[0];
}
this.postProcessReturnvalue = postProcess.doUpload(tempFtpData, this.fileName, this.interfaceId, this.processId, fileMap);
this.logger.log(PASLevel.FINE, "***** PostProcess Return::" + this.postProcessReturnvalue);
return;
}
}
catch (Exception e)
{
this.logger.log(PASLevel.SYSTEM_ERROR, ":ProcessLabel:" + this.processLabel + ":Error:" + e.getMessage(), new LogParameters(this.processId, PROCESS_NAME, this.processLabel, e));
this.postProcessReturnvalue = -1;
this.errorStr = e.getMessage();
throw e;
}
}
public void writeFileToExceptionDir()
throws Exception
{
String exceptionDirPath = EnvProperties.getProperty(PROCESS_NAME + "." + this.interfaceId + ".EXCEPTION_DIR_PATH");
try
{
Utility.createFile(exceptionDirPath + "/" + this.fileName, this.ftpData);
String message = "Error while performing post process :: " + this.fileName + ", File is stored in Exception Directory. ";
message = message = "::ErrorMessage::" + this.errorStr;
performSendErrorEmail(message);
return;
}
catch (Exception e)
{
this.logger.log(PASLevel.SYSTEM_ERROR, ":ProcessLabel:" + this.processLabel + ":Error:" + e.getMessage(), new LogParameters(this.processId, PROCESS_NAME, this.processLabel, e));
throw e;
}
}
public void writeFileToInputDir()
throws Exception
{
String inputDirPath = EnvProperties.getProperty(PROCESS_NAME + "." + this.interfaceId + ".INPUT_DIR_PATH");
try
{
String completeFileName = this.interfaceId + "." + this.fileName;
Utility.createFile(inputDirPath + "/" + completeFileName, this.ftpData);
String message = "Interface has saved the file: " + completeFileName + " to input Directory ";
performSendErrorEmail(message);
return;
}
catch (Exception e)
{
this.logger.log(PASLevel.SYSTEM_ERROR, ":ProcessLabel:" + this.processLabel + ":Error:" + e.getMessage(), new LogParameters(this.processId, PROCESS_NAME, this.processLabel, e));
throw e;
}
}
public void updateLog()
throws Exception
{
try
{
this.processLabel = (this.processLabel + ",FilesProcessed=" + this.fileCounter);
updateProcessLabel(this.processLabel);
MessageDataOperation.updateMessageSentData(this.processId, "Y");
this.logger.log(PASLevel.INFO, "Process Completed, Process Label:" + this.processLabel);
return;
}
catch (Exception e)
{
this.logger.log(PASLevel.SYSTEM_ERROR, ":ProcessLabel:" + this.processLabel + ":Error:" + e.getMessage(), new LogParameters(this.processId, PROCESS_NAME, this.processLabel, e));
throw e;
}
}
public void updateLog1()
throws Exception
{
try
{
this.processLabel += ",FilesProcessed=0";
updateProcessLabel(this.processLabel);
MessageDataOperation.updateMessageSentData(this.processId, "Y");
this.logger.log(PASLevel.INFO, "Process Completed, Process Label:" + this.processLabel);
return;
}
catch (Exception e)
{
this.logger.log(PASLevel.SYSTEM_ERROR, ":ProcessLabel:" + this.processLabel + ":Error:" + e.getMessage(), new LogParameters(this.processId, PROCESS_NAME, this.processLabel, e));
throw e;
}
}
}
This code makes use of a FTP timer even generator to kick off a transaction daily. The problem is, when the timer triggers its spitting out that error and at the same time the transaction is going through. I did try multiple try/catch blocks, but could not get any additional information so far. This has been happening ever since a server outage. Can anyone suggest
I try to connect to a custom Bluetooth device using BlueCove. I can pair the device, but when I try to search for services I always get SERVICE_SEARCH_DEVICE_NOT_REACHABLE in serviceSearchCompleted() and no services are discovered. If I try the same thing outside Java (in Windows), the PC bluetooth device discovers and can connect (using COM21, COM22, ...) to the SPP service on my device.
What am I doing wrong?
I also tried to do the service search after the device discovery is ended. Same issue.
Please find below my code.
Many thanks in advance for any idea on how to solve this,
Adrian.
public class Test {
private static Logger LOG = Logger.getLogger(Test.class.getName());
private static final String NAME = "XXXX";
private static final String PIN = "1234";
private static final UUID[] UUIDS = new UUID[] {new UUID(0x0003), new UUID(0x1101)};
private LocalDevice localDevice;
private DiscoveryAgent discoveryAgent;
private DiscoveryListener discoveryListener = new GDiscoveryListener();
private Map<Integer, RemoteDevice> searchForServices = new HashMap<Integer, RemoteDevice>();
private Collection<ServiceRecord> servicesDiscovered = new HashSet<ServiceRecord>();
private Object lock = new Object();
private CountDownLatch waitForDevices;
protected void connect() {
try {
localDevice = LocalDevice.getLocalDevice();
localDevice.setDiscoverable(DiscoveryAgent.GIAC);
LOG.info("Local Device: " + localDevice.getFriendlyName()
+ "(" + localDevice.getBluetoothAddress() + ")");
discoveryAgent = localDevice.getDiscoveryAgent();
LOG.finest("Start discovering devices");
discoveryAgent.startInquiry(DiscoveryAgent.GIAC, discoveryListener);
try {
synchronized(lock) {
lock.wait();
}
if (searchForServices.size() > 0) {
waitForDevices = new CountDownLatch(searchForServices.size());
waitForDevices.await();
}
}
catch (InterruptedException e) {
LOG.log(Level.WARNING, "Error waiting to terminate discovery", e);
}
LOG.finest(servicesDiscovered.size() + " services discovered");
LOG.finest("Device discovery completed");
} catch (BluetoothStateException e) {
LOG.log(Level.WARNING, "Error initializing Bluetooth", e);
}
}
private class GDiscoveryListener implements DiscoveryListener {
public void deviceDiscovered(RemoteDevice rd, DeviceClass dc) {
try {
String name = rd.getFriendlyName(false);
boolean isMine = NAME.equals(name);
LOG.info("Discovered: " + name + "(" + rd.getBluetoothAddress() + ")"
+ (isMine ? "" : " - ignoring"));
if (!isMine)
return;
if (!rd.isAuthenticated()) {
LOG.finest("Try to pair with " + name
+ " PIN: " + PIN);
boolean paired = RemoteDeviceHelper.authenticate(rd, PIN);
LOG.info("Pair with " + name + (paired ? " succesfull" : " failed"));
}
int transID = discoveryAgent.searchServices(null, UUIDS, rd, discoveryListener);
searchForServices.put(transID, rd);
LOG.finest("Searching for services for " + name + " with transaction " + transID);
} catch (BluetoothStateException e) {
LOG.log(Level.WARNING, "Cannot search services for "
+ rd.getBluetoothAddress(), e);
} catch (IOException e) {
LOG.log(Level.WARNING, "Error connecting ", e);
} catch (Throwable t) {
LOG.log(Level.WARNING, "Cannot search services for "
+ rd.getBluetoothAddress(), t);
}
}
public void inquiryCompleted(int respCode) {
synchronized(lock) {
lock.notify();
}
switch (respCode) {
case DiscoveryListener.INQUIRY_COMPLETED :
LOG.fine("INQUIRY_COMPLETED");
break;
case DiscoveryListener.INQUIRY_TERMINATED :
LOG.fine("INQUIRY_TERMINATED");
break;
case DiscoveryListener.INQUIRY_ERROR :
LOG.fine("INQUIRY_ERROR");
break;
default :
LOG.fine("Unknown Response Code - " + respCode);
break;
}
}
public void serviceSearchCompleted(int transID, int respCode) {
String rd = searchForServices.get(transID).getBluetoothAddress();
//searchForServices.remove(transID);
switch (respCode) {
case DiscoveryListener.SERVICE_SEARCH_COMPLETED:
LOG.fine(rd + ": The service search completed normally");
break;
case DiscoveryListener.SERVICE_SEARCH_TERMINATED:
LOG.fine(rd + ": The service search request was cancelled by a call to DiscoveryAgent.cancelServiceSearch(int)");
break;
case DiscoveryListener.SERVICE_SEARCH_ERROR:
LOG.warning(rd + ": An error occurred while processing the request");
break;
case DiscoveryListener.SERVICE_SEARCH_NO_RECORDS:
LOG.info(rd + ": No records were found during the service search");
break;
case DiscoveryListener.SERVICE_SEARCH_DEVICE_NOT_REACHABLE:
LOG.warning(rd + ": The device specified in the search request could not be reached or the local device could not establish a connection to the remote device");
break;
default:
LOG.warning(rd + ": Unknown Response Code - " + respCode);
break;
}
if (waitForDevices != null)
waitForDevices.countDown();
}
public void servicesDiscovered(int transID, ServiceRecord[] srs) {
LOG.info("Services discovered in transaction " + transID + " : " + srs.length);
for (ServiceRecord sr : srs) {
LOG.info(sr.getConnectionURL(ServiceRecord.NOAUTHENTICATE_NOENCRYPT, false));
servicesDiscovered.add(sr);
}
}
}
public static void main(String[] args) {
new Test().connect();
}
}
I had the same problem while connecting to a Bluetooth earpiece. Like you I was also searching for more than one service at a time and It always returned SERVICE_SEARCH_DEVICE_NOT_REACHABLE. So, I tried searching for only one service and it worked. So, try modifying your code as:
...
private static final UUID[] UUIDS = new UUID[] {new UUID(0x0003)}