I created a cronjob in hybris 6.1. In HMC 'Start CronJob now' button is there to start cron job but 'Abort CronJob' button is not showing.What to do ????
All jobs are not abortable. To be abortable a job must implement the isAbortable method and return true.
Example :
#Override
public boolean isAbortable()
{
return true;
}
See Writing an Abortable Job.
Related
Can I run Service in background thread?
I want to load data from database and during loading data i want progress bar to be indicating progress. First I have created task, run it in background thread and then update progress bar according to this task. However, I found out that this Task is not reusable, so next time i hit the button, it didn't work. Later on, I fount out that Service can run Tasks multiple times, So i have encapsulated those tasks inside of Service.
Now it works great - every time i hit button, table is reloaded - except progress bar is not moving.
How can I reach desired result?
Okay... Here is completed code: https://mega.nz/#!yUsjgJyZ!DHfuBqsujAHurS-pQ_W5y8BAflOtvxsm48goRPkDsxA
First, i want to tell you what is my goal:
When I run program, i want the progress bar to be in indeterminate state. After pressing the button, i want progress bar to reflect progress of Service. After finishing the Service, i want the progress bar to be completed (100%).
Here is what i have found. It looks like service automatically runs it's task on background thread. I have built a "sand box" program where i was playing with services and progress bar. The program comprised of progress bar, two text fields with two buttons above them. First button can start service_countTo100 and second button can run service_getActualCount.
Now in fxml file i set progress bar to indeterminate default state. After pressing the button1, a counting has started (displayed in text_field1) and progress bar has changed according to actual progress. After pressing button2, actual value of count is displayed in text_field2. And here comes some issues. To demonstrate the issues, i will show you source code of Service:
// Create the service
public static Service<Integer> serviceTo100 = new Service<Integer>() {
#Override
protected Task<Integer> createTask() {
Task<Integer> taskTo100 = new Task<Integer>() {
#Override protected Integer call() throws Exception {
int iterations;
updateProgress(-1, 100);
for (iterations = 0; iterations < 100; iterations++) {
if (isCancelled()) {
updateMessage("Cancelled");
break;
}
updateMessage("Iteration " + iterations);
updateProgress(iterations, 100);
// Now block the thread for a short time, but be sure
// to check the interrupted exception for cancellation!
try {
Thread.sleep(100);
} catch (InterruptedException interrupted) {
if (isCancelled()) {
updateMessage("Cancelled");
break;
}
}
}
//udpateProgress(100, 100);
return iterations;
}
};
return taskTo100;
}
};
As you can see, there is a simple loop which counts from 0 to 100 and there is also a updateProgress(iterations, 100); statement which updates progress. This service is located in Services class. In FXMLDocumentController.java is method called runService(Service service) defined as this:
public void runService(Service service){
service.start();
progressBar.progressProperty().bind(service.progressProperty());
service.setOnSucceeded((event) -> {
service.reset();
progressBar.progressProperty().unbind();
progressBar.setProgress(1);
});
}
The initialize looks like this:
#Override
public void initialize(URL url, ResourceBundle rb) {
btn_start1.setOnAction((event) -> {
Service service = Services.serviceTo100;
runService(service);
txt_field1.textProperty().bind(service.messageProperty());
System.out.printf("something\n");
});
.
.
.
}//end of initialize
Now the most interesting thing (at least for me, novice) comes into play.
In service definition, you can notice commented line //updateProgress(100,100). That was my try to set progress bar to completed state when counting has stopped. But java ignored that line. I tried to put System.out.print("Something"); and it worked, but updateProgress(100, 100) didn't. When counting has finished, progress bar was set to it's default state defined in fxml file, which was indeterminate.
Conclusion: Service class creates task defined inside of it and after task is completed, the task doesn't exists anymore, thus, there is no progress to be bound with progress bar.
Even though task does not exists anymore, you cannot set progress of the bounded progress bar with setProgress(double double) method. You first need to unbound it.
Now I got what i needed:
You run the program, progress bar is in indeterminate state, waiting for hit. You hit the button, service starts counting up to 100 and progress bar is progressing according to progressProperty of service. When counting is done, Progress bar is set to indeterminate state again, waiting for another start.
I have basic workflow with replicator activity inside it. Replicator contains my custom sequence activity with standard create task --> ontaskchanged --> complete task sequence.
Now: tasks are created and can be completed without problem. The thing is I cannot find a way to get a value of completed task. Was it approved or rejected ?
Please provide couple lines of code of replicator's ChildCompleted event to get anything out of Sequence activity instance (or any other way).
thanks
UPDATE: It seems in order to exchange values between instances of workflow you need to use DependencyProperty. So solution here is:
1) add DependencyProperty to parent workflow and add property which you will use to store value like this:
public static DependencyProperty childStatusProperty =
System.Workflow.ComponentModel.DependencyProperty.Register("childStatus",
typeof(string), typeof(parentWorkflowTypeName));
public string childStatus
{
get
{
return (string)base.GetValue(childStatusProperty);
}
set
{
base.SetValue(childStatusProperty, value);
}
}
2) in custom sequence activity access parent's instance and use defined DependencyProperty to set property to value like this:
private void completeTask1_MethodInvoking(object sender, EventArgs e)
{
var replicator = this.Parent;
var workflowParent = (parentWorkflowTypeName)replicator.Parent;
workflowParent.childStatus = "my custom status value";
}
3) read this value using normal property:
//from parent workflow
string status = childStatus;
The issue is that you have to record somewhere the list of all tasks created. I guess you are creating the tasks in parallel (not sequential).
I had the same issue, it took me a while to fix this.
Please check this link as a good starting point: http://rmanimaran.wordpress.com/2010/12/02/sharepoint-workflow-replicator-parallel-approval-problem-solution/
I need to execute a task periodically in Liferay, I find that you can create a class that implements MessageListener and in the receive method you can implement the action. Until here its fine, but after this to program the time you need to do it in liferay-portlet.xml, if the xml file is used I cannot edit the duration dynamically.
Is there any way I can create a task that can be programmed to dynamically get the values for scheduling duration from the DB?
I believe that with SchedulerEngineUtil I must to be able tho do this, but I don't know if it's the correct way or how do it?
Does anyone know how I can find any documentation and some example?
Thanks in advance
Exactly, to execute a task periodically you must implement MessageListener and do the following in your liferay-portlet.xml -
<scheduler-entry>
<scheduler-event-listener-class>com.#className</scheduler-event-listener-class>
<trigger>
<simple>
<simple-trigger-value>1</simple-trigger-value>
<time-unit>minute</time-unit>
</simple>
</trigger>
</scheduler-entry>
This will trigger the event listener class every 1 minute.So try fetching data from DB using Util method in here.
Let me know if that helped.
To add a dynamic scheduler you have to implement a MessageListener and register it using the SchedulerEngineHelperUtil:
String pId = "portlet id here"; // TODO put portlet ID here
Message msg = new Message();
msg.put(SchedulerEngine.PORTLET_ID, pId);
msg.put(SchedulerEngine.MESSAGE_LISTENER_CLASS_NAME, MyListener.class.getName());
Trigger listener = new IntervalTrigger(MyListener.class.getName(), MyListener.class.getName(), 50);
SchedulerEngineHelperUtil.schedule(
listener, StorageType.PERSISTED, "some description",
DestinationNames.SCHEDULER_DISPATCH, msg, 0);
You may also want to read my answer also covering a solution for creating a static scheduled-task.
The time is set in cronText, where 12 is minutes and 10 is hours. Currently this cronText makes it schedule every day at 10:12 am.
String portletId = "yourportlet_WAR_yourportlet";
String cronText = "0 12 10 1/1 * ? *";
Message message = new Message();
message.put(SchedulerEngine.MESSAGE_LISTENER_CLASS_NAME, YourListenerClass.class.getName());
message.put(SchedulerEngine.PORTLET_ID, portletId);
message.put("portletId", portletId);
SchedulerEngineHelperUtil.schedule(
new CronTrigger("jobName", "jobGroup", cronText),
StorageType.PERSISTED,
"Message Scheduler Description",
DestinationNames.SCHEDULER_DISPATCH,
message,
0);
Ok, I'm working on my final dilemna for my project. The project is an IPv4 endpoint updater for TunnelBroker's IPv6 tunnel. I have everything working, except for the timer. It works, however if the user disables the "automatic update" and reenables it, the application crashes. I need the timer to be on an thread outside of the EDT (in such a way that it can be destroyed and recreated when the user unchecks/checks the automatic update feature or changes the amount of time between updates).
What I'm pasting here is the code for the checkbox that handles automatic updates, and the timer class. Hopefully this will be enough to get an answer on how to do this (I'm thinking either it needs to be a worker, or use multi-threading--even though only one timer will be active).
private void jCheckBox1ItemStateChanged(java.awt.event.ItemEvent evt) {
// TODO add your handling code here:
// if selected, then run timer for auto update
// set time textbox to setEditable(true) and get the time from it.
// else cancel timer. Try doing this on different
// class to prevent errors from happening on reselect.
int updateAutoTime = 0;
if (jCheckBox1.isSelected())
{
updateAutoTime = Integer.parseInt(jTextField4.getText())*60*1000;
if (updateAutoTime < 3600000)
{
updateAutoTime = 3600000;
jTextField4.setText(new Integer(updateAutoTime/60/1000).toString());
}
updateTimer.scheduleAtFixedRate(new TimerTask() {
public void run()
{
// Task here ...
if (jRadioButton1.isSelected())
{
newIPAddress = GetIP.getIPAddress();
}
else
{
newIPAddress = jTextField3.getText();
}
strUsername = jTextField1.getText();
jPasswordField1.selectAll();
strPassword = jPasswordField1.getSelectedText().toString();
strTunnelID = jTextField2.getText();
strIPAddress = newIPAddress;
if (!newIPAddress.equals(oldIPAddress))
{
//fire the tunnelbroker updater class
updateIP.setIPAddress(strUsername, strPassword, strTunnelID, strIPAddress);
oldIPAddress = newIPAddress;
jLabel8.setText(newIPAddress);
serverStatus = updateIP.getStatus().toString();
jLabel6.setText(serverStatus);
}
else
{
serverStatus = "No IP Update was needed.";
jLabel6.setText(serverStatus);
}
}
}, 0, updateAutoTime);
}
else
{
updateTimer.cancel();
System.out.println("Timer cancelled");
System.out.println("Purged {updateTimer.purge()} tasks.");
}
}
As I mentioned, this works once. But if the user deselects the checkbox, it won't work again. And the user can't change the value in jTextField4 after they select the checkbox.
So, what I'm looking for is this:
How to make this so that user can select and deselect the checkbox as they want (even if it's multiple times in a row).
How to make this so the user can change the value in jTextField4, and have it automatically cancel the current timer, and start a new one with the new value (I haven't done anything with the jTextField4 at all, so I'll have to create an event to cover it later).
Thanks, and have a great day:)
Patrick.
Perhaps this task would be better suited to a javax.swing.Timer. See Timer.restart() for details.
Note that Timer is relatively inaccurate over long time periods. One way to account for that is to have it repeat frequently but perform it's assigned task only one a certain time has been reached or passed.
Would I be able to wrap everything in the "task" portion of the call to Swing Timer, or do I have to create another class that handles the task?
You might want to wrap the grunt work in a SwingWorker to ensure the EDT is not blocked.
..I'm assuming that I would have to create the timer as a class-level declaration .. correct?
Yes, that is what I was thinking.
I want to create an online test system, so i need a timer. When user start the test the timer will start counting down. But when user go to next question refresh the page the timer will still running. How can I do that any suggestion?
You can use PrimeFaces Poll option.
The counter will always be saved on the server.
You can also use PrimeFaces Extensions, they have timer in their API.
Example: you put start of the test into #SessionScoped bean, then calculate seconds remaining which will be used as an input to <pe:timer> element:
#SessionScoped
public class UserData {
private Date testStart;
/* getters and setters for testStart */
public int secondsRemaining() {
//calculate seconds remaining until end of the test from this.testStart
return secondsRemaining;
}
}
and then your test.xhtml would contain element
Time remaining: <pe:timer format="HH:mm:ss"
timeout="#{userData.secondsRemaining()}"/>