I want to create a task under Window Task Scheduler using my java code.
OS I am using is win7 64bit.
After creating the task I have to edit the scheduled time weekly or biweekly.
Is there any window scheduler API to use in java code or command to use under command prompt?
Launch the command line utility schtasks.
To create the task.
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
public class TestWinScheduler {
public static void main(String args[]) throws IOException, InterruptedException {
// schtasks /create /tn "HowToTask" /tr c:\temp\test.cmd /sc once /st 00:00:00 /sd 2022/01/01 /ru username /rp password
List<String> commands = new ArrayList<String>();
commands.add("schtasks.exe");
commands.add("/CREATE");
commands.add("/TN");
commands.add("\"HowToTask\"");
commands.add("/TR");
commands.add("\"c:/temp/test.cmd\"");
commands.add("/SC");
commands.add("once");
commands.add("/ST");
commands.add("00:00:00");
commands.add("/SD");
commands.add("2022/10/10");
commands.add("/RU");
commands.add("username");
commands.add("/RP");
commands.add("password");
ProcessBuilder builder = new ProcessBuilder(commands);
Process p = builder.start();
p.waitFor();
System.out.println(p.exitValue()); // 0 : OK
// 1 : Error
}
}
To execute a task :
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
public class TestWinScheduler {
public static void main(String args[]) throws IOException, InterruptedException {
// schtasks /run /tn "HowToTask"
List<String> commands = new ArrayList<String>();
commands.add("schtasks.exe");
commands.add("/RUN");
commands.add("/TN");
commands.add("\"HowtoTask\"");
ProcessBuilder builder = new ProcessBuilder(commands);
Process p = builder.start();
p.waitFor();
System.out.println(p.exitValue()); // 0 : OK
// 1 : Error
}
}
Ref
Windows have already a task scheduler that you can invoke from command line: Schtasks.exe
SCHTASKS /parameter [arguments]
Description:
Enables an administrator to create, delete, query, change, run and
end scheduled tasks on a local or remote system.
Parameter List:
/Create Creates a new scheduled task.
/Delete Deletes the scheduled task(s).
/Query Displays all scheduled tasks.
/Change Changes the properties of scheduled task.
/Run Runs the scheduled task on demand.
/End Stops the currently running scheduled task.
/ShowSid Shows the security identifier corresponding to a scheduled t
ask name.
/? Displays this help message.
Try this one http://yajsw.sourceforge.net/. Using "YAJSW" (Yet Another Java Service Wrapper) you can register your java service as a windows service.
Related
I’m beginner to Terraform CDK. I’ve created simple code in terraform CDK to create an EC2 instance. but here instead of run cdktf deploy in terminal I’m calling is via java processbuilder inside my main method.
Every thing good till now. My Code is compile successful and Jar build. But we I run the jar by command java -jar target/ getting the below error.
└─[$] java -jar target/irm-1.0-SNAPSHOT.jar [0:24:43]
Error: Unable to initialize main class com.example.test.Main
Caused by: java.lang.NoClassDefFoundError: software/constructs/Construct
Here is the my file structure
Here is the Main.java
package com.example.test;
import com.hashicorp.cdktf.App;
import com.hashicorp.cdktf.TerraformStack;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;
public class Main {
public static void main(String[] args) throws IOException {
final App app = new App();
TerraformStack stack = new MainStack(app, "aws_instance");
// new RemoteBackend(stack, RemoteBackendProps.builder()
// .hostname("app.terraform.io")
// .organization("<YOUR_ORG>")
// .workspaces(new NamedRemoteWorkspace("learn-cdktf"))
// .build());
app.synth();
//calling cdktf deploy
List<String> list = new ArrayList<String>();
list.add("/usr/local/bin/cdktf");
list.add("deploy");
// create the process
ProcessBuilder build = new ProcessBuilder(list);
// starting the process
Process process = build.start();
// for reading the output from stream
BufferedReader stdInput
= new BufferedReader(new InputStreamReader(
process.getInputStream()));
String s = null;
while ((s = stdInput.readLine()) != null) {
System.out.println(s);
}
}
}
Here is the MainStack.java
package com.example.test;
import software.constructs.Construct;
import com.hashicorp.cdktf.TerraformStack;
import com.hashicorp.cdktf.TerraformOutput;
import com.hashicorp.cdktf.providers.aws.AwsProvider;
import com.hashicorp.cdktf.providers.aws.ec2.Instance;
public class MainStack extends TerraformStack
{
public MainStack(final Construct scope, final String id) {
super(scope, id);
AwsProvider.Builder.create(this, "AWS")
.region("ap-south-1")
.build();
Instance instance = Instance.Builder.create(this, "compute")
.ami("ami-0e18b1d379af4e263")
.instanceType("t3a.micro")
.build();
TerraformOutput.Builder.create(this, "public_ip")
.value(instance.getPublicIp())
.build();
}
}
There are two problems I can spot here:
The error you are getting hints towards the construct package not being installed in this project. I'd recommend using the "normal" workflow of running your cdktf program by running cdktf synth or cdktf deploy in the CLI. You can also compile your program (it it's a standard program like we initialize it) by running mvn -e -q compile
It seems like you are trying to execute deploy from within your cdktf program. This won't work, it will create an infinite loop since this program is being run by the synth operation that is being run before the deploy executes. If you want to start cdktf programmatically it has to be from another program that is independent from you CDKTF application
I am trying to attach a subscriber to an event in Esper but I would like to use .epl file for that. I've been browsing repositories and I have seen examples of doing that by using annotation interfaces. I was trying to do it the same way they do it in CoinTrader, but I can't seem to get it to work. Yet, if I set the subscriber in Java, it works.
This is my project structure for reference
This is my .epl file:
module queries;
import events.*;
import configDemo.*;
import annotations.*;
create schema MyTickEvent as TickEvent;
#Name('allEvents')
#Description('test')
#Subscriber(className='configDemo.TickSubscriber')
select * from TickEvent;
#Name('tickEvent')
#Description('Get a tick event every 3 seconds')
select currentPrice from TickEvent;
This is my config file:
<?xml version="1.0" encoding="UTF-8"?>
<esper-configuration xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://www.espertech.com/schema/esper"
xsi:noNamespaceSchemaLocation="esper-configuration-6-0.xsd">
<event-type-auto-name package-name="events"/>
<auto-import import-name="annotations.*"/>
<auto-import import-name="events.*"/>
<auto-import import-name="configDemo.*"/>
This is my Subscriber interface:
package annotations;
public #interface Subscriber {
String className();
}
This is my event class:
package configDemo;
import events.TickEvent;
public class TickSubscriber {
public void update(TickEvent tick) {
System.out.println("Event registered by subscriber - Tick is: " +
tick.getCurrentPrice());
}
}
And my main file is this:
package configDemo;
import java.io.IOException;
import java.util.concurrent.CountDownLatch;
import com.espertech.esper.client.EPStatement;
import com.espertech.esper.client.deploy.DeploymentException;
import com.espertech.esper.client.deploy.DeploymentOptions;
import com.espertech.esper.client.deploy.Module;
import com.espertech.esper.client.deploy.ParseException;
public class Main {
public static EngineHelper engineHelper;
public static Thread engineThread;
public static boolean continuousSimulation = true;
public static void main(String[] args) throws DeploymentException, InterruptedException, IOException, ParseException {
engineHelper = new EngineHelper();
DeploymentOptions options = new DeploymentOptions();
options.setIsolatedServiceProvider("validation"); // we isolate any statements
options.setValidateOnly(true); // validate leaving no started statements
options.setFailFast(false); // do not fail on first error
Module queries = engineHelper.getDeployAdmin().read("queries.epl");
engineHelper.getDeployAdmin().deploy(queries, null);
CountDownLatch latch = new CountDownLatch(1);
EPStatement epl = engineHelper.getAdmin().getStatement("allEvents");
//epl.setSubscriber(new TickSubscriber());
engineThread = new Thread(new EngineThread(latch, continuousSimulation, engineHelper.getRuntime()));
engineThread.start();
}
}
As you can see the setSubscriber line is commented out. When I run it as is, I expected that the subscriber will be recognized and registered and yet it isn't. I only get the tick events flowing in the console. If I decomment the line and I run it, I get a notification after each tick that the subscriber received the event and it all works fine.
What am I doing wrong? How can I set a subscriber within the .epl file?
Assigning a subscriber is done by the application and is not something that the engine does for you. The app code would need to loop thru the statements, get the annotations "stmt.getAnnotations" and inspect these and assign the subscriber.
I have a two programs:
first, that uses Console object to read and write data
second, that should run first with some dynamically calculated arguments
Second program code looks like this:
String[] arguments = {
"cmd", "/c",
"java", "-cp", classPath
lauchClass,
// Arguments for first program
}
ProcessBuilder pb = new ProcessBuilder(arguments);
pb.environment().putAll(System.getenv());
pb.directory(workDir);
pb.inheritIO();
Process process = pb.start();
process.waitFor();
When fist programs starts from second, System.console() is null and it fails with NPE.
So, question is: is there any way to run another process with System.console() available?
The answer is simple: If you run your launcher from an IDE like Eclipse or IntelliJ IDEA, probably it does not have System.console() set in the first place, thus there is nothing the subprocess can inherit from. Just try to write something to System.console() from the launcher, it will also fail with the same error. But if you start your launcher from an interactive console like Cmd.exe or Git Bash, both the launcher and the process started via ProcessBuilder can write to System.console(). Your launcher does not even need "cmd", "/c", it works with or without those parameters.
package de.scrum_master.stackoverflow;
import java.io.File;
import java.io.IOException;
public class Launcher {
public static void main(String[] args) throws IOException, InterruptedException {
String classPath = "out/production/SO_ExternalProcessSystemConsole";
String launchClass = "de.scrum_master.stackoverflow.MyApp";
File workDir = new File(".");
System.console().printf("Hi, I am the launcher app!%n");
String[] arguments = new String[] {
// "cmd", "/c",
"java", "-cp", classPath,
launchClass
};
ProcessBuilder pb = new ProcessBuilder(arguments);
pb.environment().putAll(System.getenv());
pb.directory(workDir);
pb.inheritIO();
Process process = pb.start();
process.waitFor();
}
}
package de.scrum_master.stackoverflow;
public class MyApp {
public static void main(String[] args) {
System.console().printf("Hi, I am an externally started app!%n");
}
}
Console log when started from IntelliJ IDEA:
Exception in thread "main" java.lang.NullPointerException
at de.scrum_master.stackoverflow.Launcher.main(Launcher.java:11)
(...)
Console log when started from cmd.exe:
Hi, I am the launcher app!
Hi, I am an externally started app!
Feel free to ask any follow-up questions.
Update: If you do not mind that the external program runs in its own interactive console instead of in the IDE console, you can use the Windows command start for that purpose and then either cmd /c (windows is closed immediately after external program has ended) or cmd /k (window stays open for you to inspect the result):
package de.scrum_master.stackoverflow;
import java.io.File;
import java.io.IOException;
public class Launcher {
public static void main(String[] args) throws IOException, InterruptedException {
String classPath = "out/production/SO_ExternalProcessSystemConsole";
String launchClass = "de.scrum_master.stackoverflow.MyApp";
String[] arguments = new String[] {
"cmd", "/c", "start",
"cmd", "/k", "java", "-cp", classPath, launchClass
};
ProcessBuilder pb = new ProcessBuilder(arguments);
Process process = pb.start();
process.waitFor();
}
}
But if then you want to read/write from/to that console, you are back at square #1. You asked why you cannot inherit System.console() to a subprocess. Well, that is because it is null due to the way Eclipse and IntelliJ launch Java programs from within the IDE (see [here] for background info). But as Magnus said, you still have System.{out|in} and can use them as follows:
package de.scrum_master.stackoverflow;
import java.io.File;
import java.io.IOException;
import java.util.Scanner;
public class Launcher {
public static void main(String[] args) throws IOException, InterruptedException {
String classPath = "out/production/SO_ExternalProcessSystemConsole";
String launchClass = "de.scrum_master.stackoverflow.MyApp";
File workDir = new File(".");
System.out.println("Hi, I am the launcher app!");
String[] arguments = new String[] { "cmd", "/c", "java", "-cp", classPath, launchClass };
ProcessBuilder pb = new ProcessBuilder(arguments);
pb.environment().putAll(System.getenv());
pb.directory(workDir);
pb.inheritIO();
Process process = pb.start();
process.waitFor();
System.out.print("What is your favourite city? ");
Scanner scanner = new Scanner(System.in);
String city = scanner.nextLine();
System.out.println("I guess that " + city + " is a nice place.");
}
}
package de.scrum_master.stackoverflow;
import java.util.Scanner;
public class MyApp {
public static void main(String[] args) {
System.out.println("----------------------------------------");
System.out.println("Hi, I am an externally started app.");
System.out.print("Please enter your name: ");
Scanner scanner = new Scanner(System.in);
String name = scanner.nextLine();
System.out.println("Hello " + name + "!");
System.out.println("----------------------------------------");
}
}
Hi, I am the launcher app!
----------------------------------------
Hi, I am an externally started app.
Please enter your name: Alexander
Hello Alexander!
----------------------------------------
What is your favourite city? Berlin
I guess that Berlin is a nice place.
I have a pretty big number of files that need to be converted to a different format. The converting is done via a Java-JAR-File that gets takes the filename as a parameter. I now have a Windows batchfile that uses a for loop to loop through all the files (there is a file that contains a list of all files that need to be converted)
for /F %%i in (all_files.txt) do call java -cp %Classpath% de.xyz.Convert -xml %%i .\xml
Now the machine I want to do this on has eight cores. The number of files is about 360.000 and I would like it to take as little time as possible, so I'd like to use as many cores as possible. How would I go about using multiple cores as easy as possible? Is Windows going to be doing that on its own?
Ok, because I hadn't actually done it before, I knocked this up. It's not great, and the lib I used was a jar I created to crash after 2 mins.. Hopefully you'll be able to reverse engineer this for your needs.
package test;
import java.io.IOException;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
public class Test {
public static void main(String[] args) throws InterruptedException, IOException {
BlockingQueue<Runnable> runnableQueue = new LinkedBlockingQueue<>();
ExecutorService executorServ = new ThreadPoolExecutor(8, 8, 1, TimeUnit.MINUTES, runnableQueue);
runnableQueue.add(new RunCrash("Example")); // Add one for each file...
executorServ.shutdown();
while(!executorServ.isTerminated()) {
// running
}
}
}
class RunCrash implements Runnable {
private String fileName;
RunCrash(String fileName) {
this.fileName = fileName;
}
#Override
public void run() {
System.out.println(fileName);
try {
crash.CrashMe.main(new String[]{fileName});
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
Oh, you can let the main thread die before the others finish, I believe the JVM will keep the executor and associated queue. :)
For the first time i stored the jobs and scheduled them using crontrigger with the below code.
package com.generalsentiment.test.quartz;
import static org.quartz.CronScheduleBuilder.cronSchedule;
import static org.quartz.JobBuilder.newJob;
import static org.quartz.TriggerBuilder.newTrigger;
import java.util.Date;
import java.util.Properties;
import org.quartz.CronTrigger;
import org.quartz.JobDetail;
import org.quartz.Scheduler;
import org.quartz.SchedulerFactory;
import org.quartz.SchedulerMetaData;
import org.quartz.impl.StdSchedulerFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class CronTriggerExample {
public void run() throws Exception {
Logger log = LoggerFactory.getLogger(CronTriggerExample.class);
System.out.println("------- Initializing -------------------");
Xml config = new Xml("src/hibernate.cfg.xml", "hibernate-configuration");
Properties prop = new Properties();
prop.setProperty("org.quartz.scheduler.instanceName", "ALARM_SCHEDULER");
prop.setProperty("org.quartz.threadPool.class",
"org.quartz.simpl.SimpleThreadPool");
prop.setProperty("org.quartz.threadPool.threadCount", "4");
prop.setProperty("org.quartz.threadPool
.threadsInheritContextClassLoaderOfInitializingThread", "true");
prop.setProperty("org.quartz.jobStore.class",
"org.quartz.impl.jdbcjobstore.JobStoreTX");
prop.setProperty("org.quartz.jobStore.driverDelegateClass",
"org.quartz.impl.jdbcjobstore.StdJDBCDelegate");
prop.setProperty("org.quartz.jobStore.dataSource", "tasksDataStore");
prop.setProperty("org.quartz.jobStore.tablePrefix", "QRTZ_");
prop.setProperty("org.quartz.jobStore.misfireThreshold", "60000");
prop.setProperty("org.quartz.jobStore.isClustered", "false");
prop.setProperty("org.quartz.dataSource.tasksDataStore.driver",
config.child("session-factory").children("property").get(1).content());
prop.setProperty("org.quartz.dataSource.tasksDataStore.URL", config.child("session-
factory").children("property").get(2).content());
prop.setProperty("org.quartz.dataSource.tasksDataStore.user", config.child("session-
factory").children("property").get(3).content());
prop.setProperty("org.quartz.dataSource.tasksDataStore.password",
config.child("session-factory").children("property").get(4).content());
prop.setProperty("org.quartz.dataSource.tasksDataStore.maxConnections", "20");
// First we must get a reference to a scheduler
SchedulerFactory sf = new StdSchedulerFactory(prop);
Scheduler sched = sf.getScheduler();
System.out.println("------- Initialization Complete --------");
System.out.println("------- Scheduling Jobs ----------------");
// jobs can be scheduled before sched.start() has been called
// job 1 will run exactly at 12:55 daily
JobDetail job = newJob(SimpleJob.class).withIdentity("job2", "group2").build();
CronTrigger trigger = newTrigger().withIdentity("trigger2", "group2")
.withSchedule(cronSchedule("00 15 15 * *
?")).build();
Date ft = sched.scheduleJob(job, trigger);
System.out.println(sched.getSchedulerName());
System.out.println(job.getKey() + " has been scheduled to run at: " + ft
+ " and repeat based on expression: "
+ trigger.getCronExpression());
System.out.println("------- Starting Scheduler ----------------");
/*
* All of the jobs have been added to the scheduler, but none of the
* jobs will run until the scheduler has been started. If you have
* multiple jobs performing multiple tasks, then its recommended to
* write it in separate classes, like SimpleJob.class writes
* organization members to file.
*/
sched.start();
System.out.println("------- Started Scheduler -----------------");
System.out.println("------- Waiting five minutes... ------------");
try {
// wait five minutes to show jobs
Thread.sleep(300L * 1000L);
// executing...
} catch (Exception e) {
}
System.out.println("------- Shutting Down ---------------------");
sched.shutdown(true);
System.out.println("------- Shutdown Complete -----------------");
SchedulerMetaData metaData = sched.getMetaData();
System.out.println("Executed " + metaData.getNumberOfJobsExecuted() + " jobs.");
}
public static void main(String[] args) throws Exception {
CronTriggerExample example = new CronTriggerExample();
example.run();
}
}
And the details are stored in Tables - QRTZ_CRON_TRIGGERS, QRTZ_JOB_DETAILS & QRTZ_TRIGGERS
My doubt is How to schedule the jobs that are stored in DB. How to display the list of jobs in a jsp page & how to trigger them automatically.
Ours is a struts2 application with Hibernate3 ORM. I am trying to initialize the quartz scheduler when the application loads. But am unable to.
Date ft = sched.scheduleJob(job, trigger);
When this is called, your job would be scheduled for the next fire time. The scheduled job would stored in the appropriate DB tables.
To Display the list of jobs on a jsp, you should persist you job key as well as custom description of what your job entails to another DB table so that during retrieval you can retrieve this custom description as well as data Quartz persist into its own tables.
Triggering this jobs automatically is something Quartz handles for you. Once the crone expression is set to what is desired and your Job class implements org.quartz.Job, Quartz would run the execute() method at your desired next fire time
JobDetail job = newJob(SimpleJob.class).withIdentity("job2", "group2").build();
this means you will have a class named SimpleJob that implements org.quartz.Job. In that class execute() method need to be implemented. Job is triggered automatically at the time you specified by cron expression. That execute method is called when job is triggered.