Java execution in background - java

i have developed an app which executes sql jobs.
When I click on execute button the my application goes into running state and it halts untill the query is executed.
I want my app should not halt and the user should be able to enter other query and those query execution should run in background.
My question is how to run the execution of queries in background?
means when the execute button is clicked ,the remaining execution should run behind the screen.
My app is developed using struts1.3 framework.I have written the main functionality in execute() of Action Class
Code snippet of execute()
DAO dao1=new DAO();
System.out.println("Here...1");
con1=dao1.DBConnection(jndiname);
Statement st = con1.createStatement();
//status_id=1;
ResultSet rs = st.executeQuery(query);
System.out.println("Here...2");
String id = Long.toString(System.currentTimeMillis());
//int req_id = System.currentTimeMillis();
String dirTree= rsBundle.getString("CSV_DIR");
File f=new File(dirTree);
String[] directories = dirTree.split("/");
String[] lists=f.list();
for (String dir : directories )
{
if (!dir.isEmpty() )
{
if (f.exists())
{
System.out.println("directory exist");
}
if (!f.exists())
{
boolean success = (new File(dirTree).mkdirs());
if(success)
{
System.out.println("directory created");
}
}
}
}
for(String s:lists)
{
System.out.println("files.." + s);
}
String csv_file_path=dirTree+"/";
String csv_file_name=id +".csv";
//writing to csv file
CSVWriter writer = new CSVWriter(new FileWriter(csv_file_path + csv_file_name), ',',CSVWriter.NO_QUOTE_CHARACTER);
writer.writeAll(rs, true);
writer.close();
//status_id=7;
String zip_file_path=rsBundle.getString("zip_file_path");
String zip_filename=id + ".zip";
String zip_file_pwd=rsBundle.getString("zip_file_pwd");
//zip file creation
ZipUtil.zipDirWithPassword(dirTree, zip_file_path + zip_filename,zip_file_pwd);
String ftp_file_path=rsBundle.getString("ftp_file_path");
long zip_file_size= new File(zip_file_path + zip_filename).length();
System.out.println("File size..inside" + zip_file_size);
System.out.println("Here...3");
String exec_id=(String)request.getSession().getAttribute("userLoginId");
//int executor_id= Integer.parseInt(exec_id);
DateFormat dateFormat = new SimpleDateFormat("mm/dd/yyyy");
//get current date time with Date()
Date date = new Date();
System.out.println(dateFormat.format(date));
String query4 = "select executor_id,email_id from m_executor where windows_id = '" + exec_id + "'";
System.out.println("Query... " + query4);
//int i=0;
iPreparedStatement4=con.prepareStatement(query4);
iResultSet3=iPreparedStatement4.executeQuery();
while(iResultSet3.next())
{
//restriction=iResultSet2.getString(1);
exec_email=iResultSet3.getString(2);
executor_id=iResultSet3.getInt(1);
}
ValueListForExec db= new ValueListForExec();
String status_name="";
status_name=db.getStatusName(status_id);
if(zip_file_size <= 5242880){
System.out.println("send via email");
/*}
else
{*/
System.out.println("send via FTP");
upload.upload(host, usrname, pwd,zip_file_path + zip_filename, ftp_file_path,zip_filename);
}
String insertquery="{ call sp_process_job (?,?,?,?) }";
cs = con.prepareCall(insertquery.toString());
cs.setString(1,id);
cs.setString(2,host);
cs.setString(3,usrname);
cs.setString(4,pwd);
cs.execute();
con.commit();

You are about to enter the world of threading.
To run a task in the background you need to start that task on a separate thread.
If you are running in a Swing app you will need to ensure that you are not running the task on the event-dispatcher thread.
Have a look at SwingUtilities invokeLater.

You can use ExecutorService or Java Threads to do this job . You can write you sql job in Runnable/Callable object and once user click the button job should be given to other thread which will execute in background.Even you can use Thread Pool to transfer jobs to pooled thread.

Related

Extracting .pst file to msg but not getting exact number of msg file

I am trying to extract pst file into msg.
I am using aspose jar. I share my code where we get exact number of file in each subfolder.
public static void displayFolderAndMessageInformationForPSTFile(String dataDir) {
// Load the Outlook PST file
PersonalStorage pst = PersonalStorage.fromFile(dataDir + "allen.pst");
// Get the folders information
FolderInfoCollection folderInfoCollection = pst.getRootFolder().getSubFolders();
// Browse through each folder to display folder name and number of messages
for (int i = 0; i < folderInfoCollection.size(); i++) {
FolderInfo folderInfo = (FolderInfo) folderInfoCollection.get_Item(i);
System.out.println("FolderId: " + folderInfo.getEntryIdString());
System.out.println("Folder: " + folderInfo.getDisplayName());
System.out.println("Total items: " + folderInfo.getContentCount());
System.out.println("Total unread items: " + folderInfo.getContentUnreadCount());
System.out.println("-----------------------------------");
}
}
FolderId: AAAAAJJu05VTxVRJlC5mJefQvVeCgAAA
Folder: Inbox
Total items: 66
Total unread items: 0
But when extract message content then i get different number of msg. It give only 49 msg in inbox folder.
The following below code:
public static void main(String[] args) {
String pstFileName = dataDir + "allen.pst";
// Load the Outlook PST file
PersonalStorage pst = PersonalStorage.fromFile(pstFileName);
// Get the folders and messages information
FolderInfo folderInfo = pst.getRootFolder();
// Create a folder for this PST
String strRootFolderName = "allen.pst".replace(".pst", "") + ".Java";
new File(dataDir + strRootFolderName).mkdir();
// Call the recursive method to extract msg files from each folder
extractMsgFiles(folderInfo, pst, dataDir + strRootFolderName);
}
private static void extractMsgFiles(FolderInfo folderInfo, PersonalStorage pst, String strPSTFile) {
// Display the folder name
System.out.println("Folder: " + folderInfo.getDisplayName());
// Create folder to store the messages
String folderName = strPSTFile + "\\" + folderInfo.getDisplayName();
new File(folderName).mkdir();
// Loop through all the messages in this folder
MessageInfoCollection messageInfoCollection = folderInfo.getContents();
for (int i = 0; i < messageInfoCollection.size(); i++) {
MessageInfo messageInfo = (MessageInfo) messageInfoCollection.get_Item(i);
System.out.println("Saving message " + messageInfo.getSubject() + "....");
// Get the message in MapiMessage instance
MapiMessage message = pst.extractMessage(messageInfo);
// Delete special characters which are invalid to use as windows file name
String messageName = null;
if (message.getSubject() == null || message.getSubject().isEmpty() == true) {
messageName = getRidOfIllegalFileNameCharacters(messageInfo.getEntryIdString());
} else {
messageName = getRidOfIllegalFileNameCharacters(message.getSubject());
}
// Save this message to disk in MSG format
message.save(folderName + "\\" + messageName + ".msg");
}
// Call this method recursively for each subfolder
if (folderInfo.hasSubFolders() == true) {
for (int i = 0; i < folderInfo.getSubFolders().size(); i++) {
FolderInfo subfolderInfo = (FolderInfo) folderInfo.getSubFolders().get_Item(i);
extractMsgFiles(subfolderInfo, pst, strPSTFile);
}
}
}
Help me... Where did i make mistake ? I am new in Aspose.
Please have a look at the following code snippet for extracting message files. You may use this method in place of your extractMsgFiles method.
private static void ExtractMsgFiles(FolderInfo folderInfo, PersonalStorage pst)
{
// display the folder name
Console.WriteLine("Folder: " + folderInfo.DisplayName);
Console.WriteLine("==================================");
// loop through all the messages in this folder
MessageInfoCollection messageInfoCollection = folderInfo.GetContents();
foreach (MessageInfo messageInfo in messageInfoCollection)
{
Console.WriteLine("Saving message {0} ....", messageInfo.Subject);
// get the message in MapiMessage instance
MapiMessage message = pst.ExtractMessage(messageInfo);
// save this message to disk in msg format
message.Save(message.Subject.Replace(":", " ") + ".msg");
// save this message to stream in msg format
MemoryStream messageStream = new MemoryStream();
message.Save(messageStream);
}
// Call this method recursively for each subfolder
if (folderInfo.HasSubFolders == true)
{
foreach (FolderInfo subfolderInfo in folderInfo.GetSubFolders())
{
ExtractMsgFiles(subfolderInfo, pst);
}
}
}
You may visit the link Working with Messages in a PST File in case you are interested in more details.
I work with Aspose as Developer evangelist.
The emails not having unique subject names could be causing this issue? I had this exact issue when doing something similar in Powershell. Putting an autonumber in the filename could help get around this.

Database insertion synchronization

I have a java code that generates a request number based on the data received from database, and then updates the database for newly generated
synchronized (this.getClass()) {
counter++;
System.out.println(counter);
System.out.println("start " + System.identityHashCode(this));
certRequest
.setRequestNbr(generateRequestNumber(certInsuranceRequestAddRq
.getAccountInfo().getAccountNumberId()));
System.out.println("outside funcvtion"+certRequest.getRequestNbr());
reqId = Utils.getUniqueId();
certRequest.setRequestId(reqId);
System.out.println(reqId);
ItemIdInfo itemIdInfo = new ItemIdInfo();
itemIdInfo.setInsurerId(certRequest.getRequestId());
certRequest.setItemIdInfo(itemIdInfo);
dao.insert(certRequest);
addAccountRel();
counter++;
System.out.println(counter);
System.out.println("end");
}
the output for System.out.println() statements is `
1
start 27907101
com.csc.exceed.certificate.domain.CertRequest#a042cb
inside function request number66
outside funcvtion66
AF88172D-C8B0-4DCD-9AC6-12296EF8728D
2
end
3
start 21695531
com.csc.exceed.certificate.domain.CertRequest#f98690
inside function request number66
outside funcvtion66
F3200106-6033-4AEC-8DC3-B23FCD3CA380
4
end
In my case I get a call from two threads for this code.
If you observe both the threads run independently. However the data for request number is same in both the cases.
is it possible that before the database updation for first thread completes the second thread starts execution.
`
the code for generateRequestNumber() is as follows:
public String generateRequestNumber(String accNumber) throws Exception {
String requestNumber = null;
if (accNumber != null) {
String SQL_QUERY = "select CERTREQUEST.requestNbr from CertRequest as CERTREQUEST, "
+ "CertActObjRel as certActObjRel where certActObjRel.certificateObjkeyId=CERTREQUEST.requestId "
+ " and certActObjRel.certObjTypeCd=:certObjTypeCd "
+ " and certActObjRel.certAccountId=:accNumber ";
String[] parameterNames = { "certObjTypeCd", "accNumber" };
Object[] parameterVaues = new Object[] {
Constants.REQUEST_RELATION_CODE, accNumber };
List<?> resultSet = dao.executeNamedQuery(SQL_QUERY,
parameterNames, parameterVaues);
// List<?> resultSet = dao.retrieveTableData(SQL_QUERY);
if (resultSet != null && resultSet.size() > 0) {
requestNumber = (String) resultSet.get(0);
}
int maxRequestNumber = -1;
if (requestNumber != null && requestNumber.length() > 0) {
maxRequestNumber = maxValue(resultSet.toArray());
requestNumber = Integer.toString(maxRequestNumber + 1);
} else {
requestNumber = Integer.toString(1);
}
System.out.println("inside function request number"+requestNumber);
return requestNumber;
}
return null;
}
Databases allow multiple simultaneous connections, so unless you write your code properly you can mess up the data.
Since you only seem to require a unique growing integer, you can easily generate one safely inside the database with for example a sequence (if supported by the database). Databases not supporting sequences usually provide some other way (such as auto increment columns in MySQL).

Execution Time exceed Quartz Scheduler Trigger every minute

I have questions on how to use the scheduler properly.
I'm running a scheduler that trigger a job that sends list of emails at 10:00 am on working days.
The scheduler will trigger the job every 1 minute. However, the execution time for sending an email will take around 5 seconds.
Therefore, if I have 20 emails to send out for a day, it will take 20x5sec = 100 sec.
The scheduler will trigger after 1 minute, before the 20 emails being sent out completely.
Therefore, some emails will be left unsent.
Please kindly advise me on how do I send out the email completely before the next trigger time ?
Below is my sample code.
//CalendarReminder.java
// Job 1 & Group 1
JobDetail job = new JobDetail();
job.setName("Job1");
job.setJobClass(SendEmailJob.class);
job.setGroup("group1");
//example of adding an excluded day of the week - This excludes sundays from job
//firing schedule
WeeklyCalendar weeklyOff = new WeeklyCalendar();
weeklyOff.setDayExcluded(Calendar.SUNDAY, true);
// Trigger 1
//configure the scheduler time
SimpleTrigger trigger = new SimpleTrigger();
trigger.setStartTime(new Date(System.currentTimeMillis() + 1000));
trigger.setRepeatCount(SimpleTrigger.REPEAT_INDEFINITELY);
trigger.setRepeatInterval(60000); // Trigger every 1 min
trigger.setGroup("group1");
trigger.setName("trigger1");
try{
//schedule the job
scheduler = new StdSchedulerFactory().getScheduler();
scheduler.addCalendar("weeklyOff", weeklyOff, false, true);
scheduler.start();
scheduler.scheduleJob(job, trigger);
}catch(Exception ex){
}
-----------------------------------------------------------------------------
//SendEmailJob.java
try {
//getting database connection to MySQL server
dbCon = DriverManager. getConnection(dbURL, username, password);
//getting PreparedStatment to execute query
stmt = dbCon.prepareStatement(query);
//Resultset returned by query
rs = stmt.executeQuery(query);
while(rs.next()){
Str_Company = rs.getString("erscheduledemail.company");
Str_Dept = rs.getString("erscheduledemail.dept");
Str_EventType = rs.getString("erscheduledemail.eventtype");
Str_OneTimeDate = rs.getString("erscheduledemail.onetimedate");
Str_TimeSend = rs.getString("erscheduledemail.timesend");
Str_EmailFrom = rs.getString("erscheduledemail.emailfrom");
Str_EmailTo = rs.getString("erscheduledemail.emailto");
Str_EmailCCTo = rs.getString("erscheduledemail.emailccto");
Str_EmailSubject = rs.getString("erscheduledemail.emailsubject");
Str_EmailMessage = rs.getString("erscheduledemail.emailmessage");
Str_DeliveryStatus = rs.getString("erscheduledemail.deliverystatus");
Str_ActiveStatus = rs.getString("erscheduledemail.activestatus");
// Retrieve Scheduled Records Date yyyy-mm-dd & Time hh:mm:ss
Int_Year = Integer.parseInt(Str_OneTimeDate.substring(0, 4));
Int_Month = Integer.parseInt(Str_OneTimeDate.substring(5, 7));
Int_Day = Integer.parseInt(Str_OneTimeDate.substring(8,10));
Int_Hour = Integer.parseInt(Str_TimeSend.substring(0, 2));
Int_Min = Integer.parseInt(Str_TimeSend.substring(3, 5));
Int_Sec = Integer.parseInt(Str_TimeSend.substring(6, 8));
// Retrieve Computer System Date & Time
Calendar SysCalen = Calendar.getInstance();
int sys_calYear = SysCalen.get(Calendar.YEAR);
int sys_calMonth = SysCalen.get(Calendar.MONTH) + 1;
int sys_calDay = SysCalen.get(Calendar.DAY_OF_MONTH);
int sys_calHour = SysCalen.get(Calendar.HOUR_OF_DAY);
int sys_calMinute = SysCalen.get(Calendar.MINUTE);
int sys_calSecond = SysCalen.get(Calendar.SECOND);
// If the time match at 10:00 am
if(sys_calYear == Int_Year && sys_calMonth == Int_Month && sys_calDay == Int_Day &&
sys_calHour == Int_Hour && sys_calMinute == Int_Min /*&& sys_calSecond == Int_Sec*/){
System.out.println( " The time now" + String.valueOf(sys_calHour) + ":" +
String.valueOf(sys_calMinute) + ":" + String.valueOf(sys_calSecond));
System.out.println( " company: " +Str_Company);
SendingEmail(Str_EmailFrom,Str_EmailTo,Str_EmailCCTo, Str_EmailSubject, Str_
EmailMessage);
// Update deliverystatus to Yes and ActiveStatus to No
stm = dbCon.createStatement();
sql = "UPDATE erscheduledemail SET deliverystatus = 'Y', activestatus = 'N' "
+
"WHERE company = '"+Str_Company+"' and dept = '"+Str_Dept+"' and onetimedate =
'"+Str_OneTimeDate+"' and eventtype = '"+Str_EventType+"' ";
//Execute INSERT SQL Statement
stm.executeUpdate(sql) ;
}
}
dbCon.close();
} catch (SQLException ex) {
//System.out.println("SQL Exception thrown :" + ex);
System.out.println("SQL Exception thrown :" + ex);
}
Thanks & Regards,
Goshen

How to retrieve new incoming data by polling and feed it back

Here the method reads the database which has an unique ID with the sequence number which keeps on increasing, since am a beginner in java,can I know how to implement this repetitive polling and check for new incoming message each time.
public void run() {
int seqId = 0;
while(true) {
List<KpiMessage> list = null;
try {
list = fullPoll(seqId);
if (!list.isEmpty()) {
seqId = list.get(0).getSequence();
incomingMessages.addAll(list);
System.out.println("waiting 3 seconds");
System.out.println("new incoming message");
Thread.sleep(3000);
}
} catch (Exception e1) {
e1.printStackTrace();
}
}
}
//Method which defines polling of the database and also count the number of Queries
public List<KpiMessage> fullPoll(int lastSeq) throws Exception {
Statement st = dbConnection.createStatement();
ResultSet rs = st.executeQuery("select * from msg_new_to_bde where ACTION = 804 and SEQ >" + lastSeq + "order by SEQ DESC");
List<KpiMessage> pojoCol = new ArrayList<KpiMessage>();
while (rs.next()) {
KpiMessage filedClass = convertRecordsetToPojo(rs);
pojoCol.add(filedClass);
}
for (KpiMessage pojoClass : pojoCol) {
System.out.print(" " + pojoClass.getSequence());
System.out.print(" " + pojoClass.getTableName());
System.out.print(" " + pojoClass.getAction());
System.out.print(" " + pojoClass.getKeyInfo1());
System.out.print(" " + pojoClass.getKeyInfo2());
System.out.println(" " + pojoClass.getEntryTime());
}
// return seqId;
return pojoCol;
}
My goal is to Poll the table from the database and also check for new incoming message, which I can find from the Header field SequenceID in table which is unique and keeps on increasing for new entries. Now my problem is
1.Lets say after I poll the first time, it reads all the entries and makes the thread to sleep for 6 seconds, by the mean time how can I get the new incoming data and Poll it again ?
2.Also how to add the new data ,when it does Polling for the second time and pass the new data to another class.
Poller calls fullPoll every 6 secs and passes lastSeq param to it. Initially lastSeq = 0. When Poller gets result list it replaces the lastSeq with max SEQ value. fullPoll retrieves only records with SEQ > lastSeq.
void run() throws Exception {
int seqId = 0;
while(true) {
List<KpiMessage> list = fullPoll(seqId);
if (!list.isEmpty()) {
seqId = list.get(0).getSequene();
}
Thread.sleep(6000);
}
}
public List<KAMessage> fullPoll(int lastSeq) throws Exception {
...
ResultSet rs = st.executeQuery("select * from msg_new_to_bde where ACTION = 804 and SEQ > " + lastSeq + " order by SEQ
DESC");
..
}
Here is some code you may use to get working on. I tried to make it pretty flexible using the Observer pattern; this way you can connect multiple "message processors" to the same poller:
public class MessageRetriever implements Runnable {
private int lastID;
private List<MessageListener> listeners;
...
public void addMessageListener(MessageListener listener) {
this.listeners.add(listener)
}
public void removeMessageListener(MessageListener listener) {
this.listeners.remove(listener)
}
public void run() {
//code to repeat the polling process given some time interval
}
private void pollMessages() {
if (this.lastID == 0)
this.fullPoll()
else
this.partialPoll()
}
private void fullPoll() {
//your full poll code
//assuming they are ordered by ID and it haves the ID field - you should
//replace this code according to your structure
this.lastID = pojoCol.get(pojoCol.length() - 1).getID()
this.fireInitialMessagesSignal(pojoCol)
}
private void fireInitialMessagesSignal(List<KAMessage> messages) {
for (MessageListener listener : this.listeners)
listener.initialMessages(messages)
}
private void partialPoll() {
//code to retrieve messages *past* the lastID. You could do this by
//adding an extra condition on your where sentence e.g
//select * from msg_new_to_bde where ACTION = 804 AND SEQ > lastID order by SEQ DESC
//the same as before
this.lastID = pojoCol.get(pojoCol.length() - 1).getID()
this.fireNewMessagesListener(pojoCol)
}
private void fireNewMessagesListener(List<KAMessage> messages) {
for (MessageListener listener : this.listeners)
listener.newMessages(messages)
}
}
And the interface
public interface MessageListener {
public void initialMessages(List<KAMessage> messages);
public void newMessages(List<KAMessage> messages)
}
Basically, using this approach, the retriever is a runnable (can be executed on it's own thread) and takes care of the whole process: does an initial poll and continues doing "partial" polls on given intervals.
Different events fire different signals, sending the affected messages to the registered listeners, and those process the messages as they want.

Chat app popup a window at client

I made a simple chat app. It uses database, this is not efficient cause the client queries database every few sec. Any way, I achieved what i needed, There are good ways out there like polling and commet, I will implement those later. Please take time to read abt this, I have few probs with this.
1) Consider two users 100 and 101, When 100 sends a msg to 101, i am saving the id as 100_101 in DB
2) When 101 send back msg to 100 it is saved as 101_100 in DB.
3) I am able to get the messages in order.
Problem-
1) Users should keep tht particular window open.
I want popup to open when there is new message. How to achieve that.
2) When a user(100) is typing user(101) should see the text as "100 is typing" if 101 chat window with 100 is open only. This should not involve any database stuff.
Work I have done. I can send data to server when user(100) starts typing to server. How to send data, i.e how to push data to user(101).
My presnt code is below.
ajax
$.ajax( {
type : "POST",
data : "uName=" + uName +"&opName=" + opName + "&msg=" + msg + "&colorCode="
+ colorCode,
url : "<%= path %>/chat/SaveChat",
error : function(xhr, ajaxOptions, thrownError) {
alert(xhr.status);
alert(thrownError);
},
success : function(data) {
// alert(data);
$("#chat-area").html(data);
document.getElementById('chat-area').scrollTop = document.getElementById('chat-area').scrollHeight;
}
});
Servlet
try {
String newline = System.getProperty("line.separator");
String uName = req.getParameter("uName");
String opName= req.getParameter("opName");
String msg = req.getParameter("msg");
String colorCode = req.getParameter("colorCode");
DateFormat dateFormat = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
Date date = new Date();
String dat =dateFormat.format(date);
PreparedStatement ps = db.conn.prepareStatement("INSERT INTO chatmessage"
+ "(message,username,msgtime,colorselected) "
+ " VALUES(?,?,?,?)");
ps.setString(1,msg);
ps.setString(2,uName+"_"+opName);
ps.setString(3,dat);
ps.setString(4,colorCode);
ps.executeUpdate();
ps.close();
ps = db.conn.prepareStatement("select * from chatmessage where username=? or username=? order by id asc");
ps.setString(1,uName+"_"+opName);
ps.setString(2,opName+"_"+uName);
ResultSet rs=ps.executeQuery();
String temp[];
StringBuilder sb = new StringBuilder();
while(rs.next())
{
temp=rs.getString("username").split("_");
/* out.println(newline);
out.print(temp[0]+":");
out.print(rs.getString("message"));
out.println(newline);*/
sb.append("<span style='background:#"
+ rs.getString("colorselected") + "'>" + temp[0]
+ "</span>" + rs.getString("message") + "<br/><br/>");
}
db.conn.close();
out.print(replaceEmoticons(sb.toString()));
//out.print("success");
}
catch(Exception ce){
out.println("<font size='30' color='red'>Error Code 004</font>");
// RequestDispatcher rd = req.getRequestDispatcher("../status/error.jsp");
// rd.forward(req, res);
}finally{
try{
db.conn.close();
}catch(Exception e){}
}
Thankyou any easy and valid ideas are appreciated.

Categories

Resources