I am running a PHP code using java.lang.Process, I want to return a value as a result from the PHP code so I can get it from Process, how can I do that ?
This is the code I am using:
public void callPhpListener(String handler, String logFile, String messageId) throws Exception {
try {
LOGGER.info("Calling PHP executore with message id:" + messageId);
// LOGGER.info("Handler:" + handler + ", logFile:" + logFile + ", message id:" + messageId);
Process exec = Runtime.getRuntime().exec(
new String[] {"/bin/bash", "-c",
"php " + handler + " " + messageId +
" >> " + logFile + " 2>&1"});
exec.waitFor();
int exitValue = exec.exitValue();
LOGGER.info("exit value is " + exitValue);
if(exitValue != 0) {
throw new Exception("Processed with error");
}
LOGGER.info("Done processing message with id:" + messageId);
} catch (Exception e) {
LOGGER.error(e.getMessage());
throw new Exception();
}
}
Related
My problem is that I do a post request to get the total number of elements in my db and I need to do a for loop until I reach that number integer division 10.
My current not working code
protected Mono<List<Long>> getAllSubscriptionIds(ProductCode productCode) {
List<Long> subscriptionIds = new ArrayList<>();
String body = "{\n" +
" \"productCodes\": [\"" + productCode.name() + "\"],\n" +
" \"pagination\": {\n" +
" \"offset\": 0,\n" +
" \"limit\": 10" +
"\n }\n" +
" }";
//first post where I get the number of elements in my db
return restClient.post(
"https://" + url,
buildRequiredHeaders(),
body,
String.class
)
.onErrorMap(err-> new RuntimeException(err.getMessage()))
.flatMap(response -> {
log.debug(response);
ResponseModel<DataLakeCallResponse<JsonNode>> variable = null;
try {
variable = JsonUtil.fromString(response, new TypeReference<ResponseModel<DataLakeCallResponse<JsonNode>>>() {
});
log.debug(response);
} catch (IOException e) {
throw new RuntimeException(e);
}
variable.getPayload().getList().forEach(
object-> subscriptionIds.add(object.get("subscriptionId").asLong()));
//if number of elements > 10
if(variable.getPayload().getPagination().getResultCount() > 10){
//for loop on that number / 10 (so that I can use an offset
for (int i = 0; i < variable.getPayload().getPagination().getResultCount() / 10; i++){
String bodyI = "{\n" +
" \"productCodes\": [\"" + productCode.name() + "\"],\n" +
" \"pagination\": {\n" +
" \"offset\": " + (i + 1) * 10 + ",\n" +
" \"limit\": 10\n" +
" }\n" +
" }";
return restClient.post(
"https://" + url,
buildRequiredHeaders(),
bodyI,
String.class
)
.onErrorMap(err-> new RuntimeException(err.getMessage()))
.flatMap(resp -> {
ResponseModel<DataLakeCallResponse<JsonNode>> varia = null;
try {
varia = JsonUtil.fromString(resp, new TypeReference<ResponseModel<DataLakeCallResponse<JsonNode>>>() {
});
} catch (IOException e) {
throw new RuntimeException(e);
}
varia.getPayload().getList().forEach(
object-> subscriptionIds.add(object.get("subscriptionId").asLong()));
return Mono.just(subscriptionIds);
});
}
}
return Mono.just(subscriptionIds);
});
}
I do understand why this does not work (it return inside the for loop) but I don't really understand what alternative can I use to make it work.
I tried an external method but it will still fail. I tried a Mono.zip but I think I tried it wrong.
This is an alternative that I tried but it still does not work.
protected Mono<Object> getAllSubscriptionIds(ProductCode productCode) {
this.counter = 0;
List<Long> subscriptionIds = new ArrayList<>();
List<Mono<Integer>> resultList = new ArrayList<>();
String body = "{\n" +
" \"productCodes\": [\"" + productCode.name() + "\"],\n" +
" \"pagination\": {\n" +
" \"offset\": 0,\n" +
" \"limit\": 10" +
"\n }\n" +
" }";
return restClient.post(
"https://" + url,
buildRequiredHeaders(),
body,
String.class
)
.onErrorMap(err-> new RuntimeException(err.getMessage()))
.flatMap(response -> {
log.debug(response);
ResponseModel<DataLakeCallResponse<JsonNode>> variable = null;
try {
variable = JsonUtil.fromString(response, new TypeReference<ResponseModel<DataLakeCallResponse<JsonNode>>>() {
});
log.debug(response);
} catch (IOException e) {
throw new RuntimeException(e);
}
variable.getPayload().getList().forEach(
object-> subscriptionIds.add(object.get("subscriptionId").asLong()));
if(variable.getPayload().getPagination().getResultCount() > 10){
for (int i = 0; i < variable.getPayload().getPagination().getResultCount() / 10; i++){
resultList.add(Mono.just(i));
}
}
return Mono.zip(resultList, intMono -> {
this.counter++;
String bodyI = "{\n" +
" \"productCodes\": [\"" + productCode.name() + "\"],\n" +
" \"pagination\": {\n" +
" \"offset\": " + this.counter * 10 + ",\n" +
" \"limit\": 10\n" +
" }\n" +
" }";
return restClient.post(
"https://" + url,
buildRequiredHeaders(),
bodyI,
String.class
)
.onErrorMap(err-> new RuntimeException(err.getMessage()))
.flatMap(resp -> {
ResponseModel<DataLakeCallResponse<JsonNode>> varia = null;
try {
varia = JsonUtil.fromString(resp, new TypeReference<ResponseModel<DataLakeCallResponse<JsonNode>>>() {
});
} catch (IOException e) {
throw new RuntimeException(e);
}
varia.getPayload().getList().forEach(
object-> subscriptionIds.add(object.get("subscriptionId").asLong()));
return Mono.just(subscriptionIds);
});
});
// return Mono.just(subscriptionIds);
});
}
Any idea how to solve this?
the issue with your code is that you are returning inside the for loop, which causes the function to return immediately after the first iteration of the loop. Instead of returning, you can use the flatMap operator to keep the pipeline going and add the results of each iteration to the subscriptionIds
Ok finally I got a solution
protected Flux<Object> getAllSubscriptionIds(ProductCode productCode) {
List<Long> subscriptionIds = new ArrayList<>();
AtomicInteger i = new AtomicInteger();
String body = "{\n" +
" \"productCodes\": [\"" + productCode.name() + "\"],\n" +
" \"pagination\": {\n" +
" \"offset\": 0,\n" +
" \"limit\": 1000" +
"\n }\n" +
" }";
return restClient.post(
"https://" + url,
buildRequiredHeaders(),
body,
String.class
)
.onErrorMap(err-> new RuntimeException(err.getMessage()))
.flatMapMany(response -> {
log.debug(response);
ResponseModel<DataLakeCallResponse<JsonNode>> variable = null;
try {
variable = JsonUtil.fromString(response, new TypeReference<ResponseModel<DataLakeCallResponse<JsonNode>>>() {
});
log.debug(response);
} catch (IOException e) {
throw new RuntimeException(e);
}
variable.getPayload().getList().forEach(
object-> subscriptionIds.add(object.get("subscriptionId").asLong()));
if(variable.getPayload().getPagination().getResultCount() > 1000){
String bodyI = "{\n" +
" \"productCodes\": [\"" + productCode.name() + "\"],\n" +
" \"pagination\": {\n" +
" \"offset\": " + i.incrementAndGet() * 1000 + ",\n" +
" \"limit\": 1000\n" +
" }\n" +
" }";
return restClient.post(
"https://" + url,
buildRequiredHeaders(),
bodyI,
String.class
)
.onErrorMap(err-> new RuntimeException(err.getMessage()))
.flatMap(resp -> {
return restClient.post(
"https://" + url,
buildRequiredHeaders(),
"{\n" +
" \"productCodes\": [\"" + productCode.name() + "\"],\n" +
" \"pagination\": {\n" +
" \"offset\": " + i.incrementAndGet() * 1000 + ",\n" +
" \"limit\": 1000\n" +
" }\n" +
" }",
String.class
)
.onErrorMap(err-> new RuntimeException(err.getMessage()))
.flatMap(respI -> {
ResponseModel<DataLakeCallResponse<JsonNode>> varia = null;
try {
varia = JsonUtil.fromString(respI, new TypeReference<ResponseModel<DataLakeCallResponse<JsonNode>>>() {
});
} catch (IOException e) {
throw new RuntimeException(e);
}
varia.getPayload().getList().forEach(
object-> subscriptionIds.add(object.get("subscriptionId").asLong()));
return Mono.just(subscriptionIds);
});
}).repeat(variable.getPayload().getPagination().getResultCount() / 1000);
}
return Mono.just(subscriptionIds);
});
}
Basically I changed the first flatMap to flatMapMany so that inside that I could have a flatMap with a repeat loop. I had to return a Flux instead of my original Mono<List> but since I know it will always result in a Mono<List> anyway I changed original caller to
return getAllSubscriptionIds(request.getEventMetadata().getProductCode()).collect(Collectors.reducing((i1, i2) -> i1)).flatMap(responseIds -> {
List<BillableApiCall> queryResults = dataLakeMapper.getBillableCallsApiCheckIban(
((ArrayList<Long>)responseIds.get()),
DateUtil.toLocalDateEuropeRome(request.getFromDate()),
DateUtil.toLocalDateEuropeRome(request.getToDate()),
request.getPagination()
);
So I had to add .collect(Collectors.reducing((i1, i2) -> i1)) (I copy/pasted this so I only guess what it does... it convert the Flux to Mono), and cast my responseIds with ((ArrayList)responseIds.get()).
repeat was not the final solution since it only repeat what's inside the flatMap (it will not repeat the post connected to it) so I had to use a trick... I removed the for loop that was not necessary, I made a post inside my flatMap repeat with another flatMap... The only missing things was to keep track of my index and I was able to find that you can use an AtomicInteger to do that.
It was not an easy task at all but I tested it and it's working.
To recap:
flatMapMany with a repeat flatMap inside (repeat only take a long as an argument, so it will repeat until it reach that value and auto-increment... but you cannot use this index for what I understand).
Another flatMap inside the flatMap repeat, that's because you cannot do another post call without this workaround as repeat will only repeat what's inside of the flatMap (not the post call before that but it can do the post call inside it).
An AtomicInteger as your index.
Change the return type to Flux, collect and cast.
Hope someone will benefit from my headache.
I have created MySQL backup dump file using Java code. While restoring dump file into MySQL Administrator it is giving MySQL error:
The selected file was generated by mysqldump and cannot be restored by this application.
Below my code for creating MySQL dump file:
public class MysqlBackup {
public boolean backupDataWithDatabase(String dumpExePath, String host, String port, String user, String password, String database, String backupPath) {
boolean status = false;
try {
Process p = null;
DateFormat dateFormat = new SimpleDateFormat("dd-MM-yyyy");
Date date = new Date();
String filepath = "backup(with_DB)-" + database + "-" + host + "-(" + dateFormat.format(date) + ").sql";
String batchCommand = "";
if (password != "") {
batchCommand = dumpExePath + " -h " + host + " --port " + port + " -u " + user + "< --password=" + password + " --add-drop-database -B " + database + " -r \"" + backupPath + "" + filepath + "\"";
} else {
batchCommand = dumpExePath + " -h " + host + " --port " + port + " -u " + user + " --add-drop-database -B " + database + " -r \"" + backupPath + "" + filepath + "\"";
}
Runtime runtime = Runtime.getRuntime();
p = runtime.exec(batchCommand);
int processComplete = p.waitFor();
if (processComplete == 0) {
FileInputStream in = new FileInputStream(backupPath + "" + filepath);
ZipOutputStream out = new ZipOutputStream(new FileOutputStream("D:\\desktop13\\serverdb.zip"));
out.putNextEntry(new ZipEntry("serverdb.sql"));
byte[] b = new byte[1024];
int count;
while ((count = in.read(b)) > 0) {
out.write(b, 0, count);
}
out.close();
in.close();
status = true;
} else {
status = false;
}
} catch (IOException ioe) {
ioe.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
return status;
}
public static void main(String[] args) {
MysqlBackup b = new MysqlBackup();
b.backupDataWithDatabase("D:\\xampp1\\mysql\\bin\\mysqldump.exe", "localhost", "3306", "root", "", "serverdb", "D:\\desktop13");
}
}
I have an application which contains a GUI, it is using Javamail. When i open this Jframe I have to see messages that are sent to my mail on a jTextArea.
The problem is when i wrote my code it only shows just the last message sent.
How do I display all new messages in my inbox?
This is my code :
private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {
Properties props = new Properties();
props.put("mail.pop3.host", "pop.gmail.com");
props.put("mail.pop3.user", "mymail#gmail.com");
props.put("mail.pop3.socketFactory", 995);
props.put("mail.pop3.socketFactory.class", "javax.net.ssl.SSLSocketFactory");
props.put("mail.pop3.port", 995);
Session session = Session.getDefaultInstance(props, new Authenticator() {
#Override
protected PasswordAuthentication getPasswordAuthentication() {
return new PasswordAuthentication("mymail#gmail.com", "mypassword");
}
});
try {
Store store = session.getStore("pop3");
store.connect("pop.gmail.com", "mymail#gmail.com", "mypaswword");
Folder fldr = store.getFolder("INBOX");
fldr.open(Folder.READ_ONLY);
Message[] msg = fldr.getMessages();
Address[] address;
for (int i = 0; i < msg.length; i++) {
jTextArea1.setText("SentDate : " + msg[i].getSentDate() + "\n" + "From : " + msg[i].getFrom()[0] + "\n" + "Subject : " + msg[i].getSubject() + "\n" + "Message : " + "\n" + msg[i].getContent().toString());
}
fldr.close(true);
store.close();
} catch (Exception e) {
System.out.println(e);
}
You repeatedly set the text of the jTextArea1 to the same contents in your loop over messages here:
for (int i = 0; i < msg.length; i++) {
jTextArea1.setText("SentDate : " + msg[i].getSentDate() + "\n" + "From : " + msg[i].getFrom()[0] + "\n" + "Subject : " + msg[i].getSubject() + "\n" + "Message : " + "\n" + msg[i].getContent().toString());
}
You should build a StringBuilder with all the messages and then set the contents of the jTextArea1
final StringBuilder sb = new StringBuilder();
for (int i = 0; i < msg.length; i++) {
sb.append("SentDate : " + msg[i].getSentDate() + "\n" + "From : " + msg[i].getFrom()[0] + "\n" + "Subject : " + msg[i].getSubject() + "\n" + "Message : " + "\n" + msg[i].getContent().toString());
}
jTextArea1.setText(sb.toString());
You can then make this a lot more legible by using an enhanced for loop and using the append method of the StringBuilder.
final StringBuilder sb = new StringBuilder();
for (Message message : msg) {
sb.append("SentDate : ").
append(message.getSentDate()).
append("\n").
append("From : ").
append(message.getFrom()[0]).
append("\n").append("Subject : ").
append(message.getSubject()).
append("\n").
append("Message : ").
append("\n").
append(message.getContent().toString());
}
jTextArea1.setText(sb.toString());
final StringBuilder sb = new StringBuilder();
for (Message message : msg) {
sb.append("SentDate : ").
append(message.getSentDate()).
append("\n").
append("From : ").
append(message.getFrom()[0]).
append("\n").append("Subject : ").
append(message.getSubject()).
append("\n").
append("Message : ").
append("\n").
append(message.getContent().toString());
}
jTextArea1.setText(sb.toString());
I have a java web application that I removed a function from the code and yet the database entries that this function writes are still being written to the database.
Inside the IssueWarrant function there is a call to insertWarrantFee that has been commented out.
private void issueWarrant(String CasePrefix, String CaseNumber, String HearingType, String Suspend)
{
int i = 0, intDivision = 0, pos = 0;
String SummSeq = getSummSeq(CasePrefix, CaseNumber);
String Charges = getCharges(CasePrefix, CaseNumber, HearingType);
boolean isVacated = false, isHearingFound = false;
NextBWNumber warrNbr = new NextBWNumber();
String WarrantNumber = warrNbr.getNextBWNumber();
String warrStatus = warrNbr.getNextBWNStatus();
String HearingDesc = "", Division = "";
isVacated = getVacatedStatus(CasePrefix, CaseNumber, HearingType);
isHearingFound = getHearingStatus (CasePrefix, CaseNumber, HearingType);
HearingDesc = getFormatToday() + " " + getHearingDesc(HearingType);
if (HearingDesc.length() > 30)
{
HearingDesc = HearingDesc.substring(0,30);
}
Division = getHearingJudge(CasePrefix,CaseNumber,HearingType);
intDivision = Integer.parseInt(Division);
if (intDivision < 10)
{ Division = "0" + Division; }
Statement localstmt = null;
String localqueryString;
localqueryString = "INSERT INTO " + library7 + "CMPBWPND" +
" (CASPRE, CASNUM, DEFSEQ, CHGSEQ, SUMSEQ, STSCOD, STSDAT," +
" STATUT, CHGABV, BWNBR, JUDCOD, PRVFLG, CT2FLG, DIVISN, BNDAMT," +
" BTYPE, CMNT, CUSER, TUSER, LUPDAT, SCRDAT, STATSDAT, SUMCRDAT, LUPDATE )" +
" VALUES ('" + CasePrefix + "', " + CaseNumber + ", 1, " + Charges.substring(i, i + 1) +
", " + SummSeq + ", 9, " + getShortDate() + ", 'RCP 12-A TA', 'WARRANT', '" +
WarrantNumber + "', " + intDivision + ", 'N', 1, '" + Division + "', " +
BondAmt + ", '" + BondType + "', '" + HearingDesc + "', 'TAAD', 'TAAD', " +
getShortDate() + ", " + getShortDate() + ", " + getLongDate() + ", " + getLongDate() +
", " + getLongDate() + ")";
try
{
if (!isVacated && isHearingFound)
{
localstmt = conn.createStatement();
localstmt.executeUpdate(localqueryString);
localstmt.close();
StatusMsg = "Client No Show-WI";
}
if (isVacated)
{
StatusMsg = "Client Vacated Case";
}
if (!isHearingFound)
{
StatusMsg = "Client Hearing Missing";
}
} catch (SQLException e)
{
System.out.println("IssueWarr - Error in IssueWarrant");
e.printStackTrace();
ReturnInfo = "Issuing Warrants Failed.";
success = false;
}finally
{
try
{
if (!localstmt.isClosed())
{
localstmt.close();
}
} catch (SQLException sql2)
{
System.out.println("Error trying to close connections. Exception: " + sql2.getMessage());
}
}
**//insertWarrantFee(CasePrefix, CaseNumber, SummSeq, WarrantNumber);**
updateHearingRecord(CasePrefix, CaseNumber, HearingType, Charges.substring(i, i + 1), Suspend);
for ( i = 1; i < Charges.length(); i++ )
{
insertBWPTFRecord(CasePrefix, CaseNumber, SummSeq, Charges.substring(i, i + 1));
}
if (!success)
{
StatusMsg = "Client Iss. Warrant Failure";
}
}
Here is the code that the insertWarrantFee called before it was commented out:
private void insertWarrantFee(String CasePrefix, String CaseNumber, String SummSeq, String WarrantNumber)
{
Statement localstmt = null;
String localqueryString;
ResultSet localrSet = null;
String feeAmt = null;
localqueryString = "SELECT AUTO$$ FROM " + library3 + "CMPDKTTP WHERE DKTTYP = 'W'";
try
{
localstmt = conn.createStatement();
localrSet = localstmt.executeQuery(localqueryString);
while (localrSet.next())
{
feeAmt = localrSet.getString("AUTO$$");
}
localstmt.close();
localrSet.close();
} catch (SQLException e)
{
System.out.println("IssueWarr - Error in Insert Warrant Fee SQL1");
e.printStackTrace();
ReturnInfo = "Issuing Warrants Failed.";
success = false;
}finally
{
try
{
if (!localstmt.isClosed())
{
localstmt.close();
}
} catch (SQLException sql2)
{
System.out.println("Error trying to close connections. Exception: " + sql2.getMessage());
}
}
localqueryString = "INSERT INTO " + library7 + "CMPBWTRN"
+ " (CASPRE, CASNUM, DEFSEQ, SUMSEQ, BWNBR, FEEAMT, DKTTYP, TUSER, LUPDAT)"
+ " VALUES ('" + CasePrefix + "', " + CaseNumber + ", 1, " + SummSeq + ", '" + WarrantNumber
+ "', " + feeAmt + ", 'W', 'TAAD', " + getShortDate() + ")";
try
{
localstmt = conn.createStatement();
localstmt.executeUpdate(localqueryString);
localstmt.close();
} catch (SQLException e)
{
System.out.println("IssueWarr - Insert Warrant Fee SQL2");
e.printStackTrace();
ReturnInfo = "Issuing Warrants Failed.";
success = false;
}finally
{
try
{
if (!localstmt.isClosed())
{
localstmt.close();
}
} catch (SQLException sql2)
{
System.out.println("Error trying to close connections. Exception: " + sql2.getMessage());
}
}
}
So even though the line that called insertWarrantFee is commented out a record is still being inserted into CMPBWTRN.
Any ideas how this could happen? The developer is indicating it could be a tomcat connection cache issue? Any other suggestion beside magical code?
Thanks!
Leslie
A couple of things to try:
Make sure you've redeployed the application and have restarted Tomcat. Check the timestamp of the deployed class in question.
Clean Tomcat's tmp and work directories
Open the deployed Java class using a decompiler to see whether the removed code is still in there.
Add a logging (or System.out.println) statement to the method that's commented out, and to the method calling it. See whether one or both are printed after redeploying the changes.
I am working on twitter integration with android using Twiitter4j. I am trying to fetch Home timelines and its working fine. But when i am looking to get urls included in the tweets there is no functions. Is there a functon to get tweet entites like urls etc.
Here is the code
cb = new ConfigurationBuilder();
cb.setDebugEnabled(true).setOAuthConsumerKey(Constants.CONSUMER_KEY)
.setOAuthConsumerSecret(Constants.CONSUMER_SECRET)
.setOAuthAccessToken(accessToken).setOAuthAccessTokenSecret(
accessSecret);
try {
TwitterFactory factory = new TwitterFactory(cb.build());
// gets Twitter instance with default credentials
Twitter twitter = factory.getInstance();
User user = twitter.verifyCredentials();
List<Status> statuses = twitter.getHomeTimeline();
System.out.println("Showing #" + user.getScreenName() + "'s home timeline.");
for (Status status : statuses) {
System.out.println("#" + status.getUser().getScreenName() + " - " + status.getText() + "--"+status.getURLs()+ "--"+status.getURLEntities());
}
} catch (TwitterException te) {
te.printStackTrace();
System.out.println("Failed to get timeline: " + te.getMessage());
System.exit(-1);
}
Works well with Sony's code and after that i have moved my code to async task and it shows some errors
Here is my edited code
protected String doInBackground(Void... args) {
String response = null;
try {
TwitterFactory factory = new TwitterFactory(cb.build());
// gets Twitter instance with default credentials
Twitter twitter = factory.getInstance();
User user = twitter.verifyCredentials();
ResponseList<Status> statuses = twitter.getHomeTimeline();
System.out.println("Showing #" + user.getScreenName() + "'s home timeline.");
for (Status status : statuses) {
System.out.println("#" + status.getUser().getScreenName() + " - " + status.getText() + "--"+status.getUser().getProfileImageURL());
URLEntity[] uent = status.getURLEntities();
if (uent != null) {
for (int k = 0; k < uent.length; k++) {
Log.i("URL Entity", "Dp Url " + uent[k].getDisplayURL()
+ " URL " + uent[k].getURL() + " start "
+ uent[k].getStart() + " end "
+ uent[k].getEnd());
}
}
}
} catch (TwitterException te) {
te.printStackTrace();
System.out.println("Failed to get timeline: " + te.getMessage());
System.exit(-1);
}
return response;
}
You just need to add one more line while creating object of ConfigurationBuilder
cb.setIncludeEntitiesEnabled(true);
(Hint for the next code)And you will get the Entities then,
ResponseList<Status> list = twitter.getHomeTimeline();
URLEntity[] uent = list.get(0).getURLEntities();
if (uent != null) {
for (int k = 0; k < uent.length; k++) {
Log.i("URL Entity", "Dp Url " + uent[k].getDisplayURL()
+ " URL " + uent[k].getURL() + " start "
+ uent[k].getStart() + " end "
+ uent[k].getEnd());
}
}