Use ThreadPoolTaskScheduler without using Spring framework - java

I am trying to use ThreadPoolTaskScheduler to schedule task using CRON but without using Spring framework. I created 2 task scheduler for daily and weekly.
So, far here is what i tried:
public class MyClass {
public static void main(String args[]) {
MyClass mc = new MyClass();
mc.runTaskScheduler();
}
private void runTaskScheduler() {
Runnable dailyScheduler = this::processDaily;
Runnable weeklyScheduler = this::processWeekly;
ThreadPoolTaskScheduler threadPoolTaskScheduler = new ThreadPoolTaskScheduler();
threadPoolTaskScheduler.initialize();
threadPoolTaskScheduler.schedule(dailyScheduler, new CronTrigger("0 * * * * *")); //0 * * * * *
threadPoolTaskScheduler.schedule(weeklyScheduler, new CronTrigger("0 1 * * * *")); //0 1 * * * *
}
private void processDaily() {
// some code
}
private void processWeekly() {
// some code
}
}
I am not sure if should i need to make ThreadPoolTaskScheduler threadPoolTaskScheduler = new ThreadPoolTaskScheduler(); static variable?
I tried to make a main class but not sure if I did it correct.

There are couple of things to mention...
First of all, if you use the Spring Scheduling library you are using the Spring framework. Spring is intended to make your live easier, therefore it uses a lot of preconfigured stuff, in case you do not provide any particular configuration.
If you do not want to use Spring and still need a cron like scheduling, take a look at the Quartz Job Scheduler.
Second, your Cron job is not daily and weekly, but minutely and hourly.
According to the docu, daily is 0 0 0 * * * and weekly 0 0 0 * * 0
Finally, your code works. There is no need to flag the ThreadPoolTaskScheduler as static. Of course you could turn your ThreadPoolTaskScheduler into a Singleton, if you want to use just a single instance of it. But be aware, that in the opinion of many, Singletons are a code smell.
import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler;
import org.springframework.scheduling.support.CronTrigger;
import java.util.Date;
public class MyClass {
private static ThreadPoolTaskScheduler THREAD_POOL_TASK_SCHEDULER;
public static ThreadPoolTaskScheduler getInstance () {
if (THREAD_POOL_TASK_SCHEDULER == null) {
THREAD_POOL_TASK_SCHEDULER = new ThreadPoolTaskScheduler();
THREAD_POOL_TASK_SCHEDULER.initialize();
}
return THREAD_POOL_TASK_SCHEDULER;
}
public static void main(String args[]) {
MyClass mc = new MyClass();
mc.runTaskScheduler();
}
private void runTaskScheduler() {
Runnable minutelyScheduler = this::processMinutely;
getInstance().schedule(minutelyScheduler, new CronTrigger("0 * * * * *")); //0 1 * * * *
}
private void processMinutely() {
System.out.println("Time " + new Date());
}
}
Or you could just use the scheduler as a class variable...
import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler;
import org.springframework.scheduling.support.CronTrigger;
import java.util.Date;
public class MyClass {
public static void main(String args[]) {
MyClass mc = new MyClass();
mc.runTaskScheduler();
}
private final ThreadPoolTaskScheduler threadPoolTaskScheduler;
public MyClass() {
threadPoolTaskScheduler = new ThreadPoolTaskScheduler();
threadPoolTaskScheduler.initialize();
}
private void runTaskScheduler() {
Runnable minutelyScheduler = this::processMinutely;
threadPoolTaskScheduler.schedule(minutelyScheduler, new CronTrigger("0 * * * * *")); //0 1 * * * *
}
private void processMinutely() {
System.out.println("Time " + new Date());
}
}
Both examples make sense, in case you want to avoid multiple instances of the scheduler or if you want to access it later on.

If you work with just Java and not Spring/SpringBoot your options are to use some 3d party library such as Quartz Job Scheduler or use Java provided classes for that. Here are the classes you might want to use:
ScheduledExecutorService interface and its implementation: ScheduledThreadPoolExecutor. Also look at class Executors and its method public static ScheduledExecutorService newSingleThreadScheduledExecutor().
Also, as far as 3d parties go I wrote my own scheduler. Look at Javadoc. This Background runner comes as part of Open Source MgntUtils library written and maintained by me. Also the source code of the library contains working example on how to use the Background Runner. The library including the source code can be downloaded from Github here and an example can be seen here. Also, the library can be obtained as Maven artifacts from Maven central here

Related

Vertx.io core vs reactivex verticle usage in jUnit

In my project mostly all imports relay on io.vertx.reactivex.core.Vertx package import, effectively makes whole project use reactivex (not core/vanilla) version of Vertx and it's verticles. I started to unit test a bit our application and to do so and to make it play nicely with JUint, according to this documentation following setup is needed to use JUnit and to run test cases in correct thread and verticle context:
#RunWith(VertxUnitRunner.class) /* Set the runner */
public class DaoTest {
#Rule /* Define rule to get vertx instance in test */
public RunTestOnContext rule = new RunTestOnContext();
#Test
public void exampleTest(TestContext context) {
TestClass t = new TestClass(rule.vertx());
}
}
the definition of TestClass is following:
import io.vertx.reactivex.core.Vertx; /* Mind here */
public class TestClass {
public TestClass(Vertx vertx) {
/* Something */
}
I'm unable to provide correct instance of Vertx because only one definition of RunTestOnContext exist in package io.vertx.ext.unit.junit and produces io.vertx.core.Vertx instance, which is incompatible with io.vertx.reactivex.core.Vertx that TestClass is using. Some other test utilities, like TestContext have their equivalents in reactivex packages io.vertx.reactivex.ext.unit.TestContext, but this seems not be a case for RunTestOnContext.
The question would be how to obtain correctly io.vertx.reactivex.core.Vertx instance in test context to still ensure thread and context consistency?
The vertx-unit project has only depdendency to vertx-core. And has no dependency to vertx-rx-java. And that is understandable. Therefore the RunTestOnContext is built using the io.vertx.core.Vertx as you see.
You can downcast with the vertx.getDelegate() from io.vertx.reactivex.core.Vertx to io.vertx.core.Vertx. Bu that doesnt work in the opposite direction.
Therefore your best option is to copy the code of the RunTestOnContext and create your reactivex version of it. (The fastest way is to just change the import to io.vertx.reactivex.core.Vertx and use the vertx.getDelegate() where it is accessed.)
Get RxVertx instance by rxVertx = Vertx.vertx(); & vertx instance by rxVertx.getDelegate();. Here is a full code snippet:
#RunWith(VertxUnitRunner.class)
public class MyVerticleTest {
protected Vertx vertx;
#Before
public void setUp(TestContext context) {
rxVertx = Vertx.vertx();
vertx = rxVertx.getDelegate();
Async async = context.async(1);
RxHelper.deployVerticle(rxVertx, new MyVerticle())
.subscribe(res -> async.countDown(), err -> {
throw new RuntimeException(err);
});
}
#Test
public void my_test(TestContext context) {
Async async = context.async();
rxVertx.eventBus().rxSend("address", dataToSend)
// .flatMap()
.subscribe(receivedData -> {
// assert what you want;
async.complete();
}, context::fail);
}
#After
public void tearDown(TestContext context) {
client.close();
rxVertx.close(context.asyncAssertSuccess());
}
}

How to create two instances of same java class running in same process?

I am learning Java Process and I am trying to create two instances of same java class running in same process which is a requirement.
class Chat {
public void getMessage() { * * * some implementation
}
}
class ProcessMain {
public static void main(String args[]) {
Chat c1 = new Chat();
Chat c2 = new Chat();
ProcessBuilder pb = new ProcessBuilder(c1); * * * * here is where I am stuck.
Two instances of same class should run in same process
}
}
Can anyone give me a lead?
By default Java will run the main class in a single process, on the same thread. If you want to have two classes communicate with one another you can pass c1 into a method inside of c2 and alter c1 that way.

Java exposing configuration elements to program [duplicate]

I got a class Config wich looks like that:
public Class Config {
public static int someIntValue = 0;
public static String someText = "some text";
}
What i want to do now is saving and loading that config and there is also that inital config if there is no need to load another. So the config can change at any point in the programm.
What i came up with was a Singelton like pattern
public Class Config {
public static Config instance;
private int someIntValue = 0;
private int String someText = "some text";
public static Config getInstance(){
if(instance == null)
instance = new Config();
return instance;
}
public void setInstance(Config config){
this.instance = config;
}
//getter/setter
...
}
But in the end it doesnt look like the best approach and im not quite happy with it :/
Maybe you guys can help me out with a usual / "best practice" way to do that.
Best Regards
Made
I would just use java.util.Properties, or some wrapper around it. Another good approach is java bean and something like xstream to save/load stuff.
Usually in Java for configuration use properties files. And then use ResuorseBundle for reading properties.
Your "singleton" is not a Singleton in the conventional sense.
1) Field instance must be private
2) Remove SetInstance method
3) And you should make your singleton thread safe.
If you'd consider avoiding writing the boilerplate code around java.util.Properties, you can have a look at something that does it for you: OWNER API.
It's configurable to tailor your needs and it offers some additional neat features if compared to java.util.Properties (read the docs).
Example. You define an interface with your configuration parameters:
public interface ServerConfig extends Config {
int port();
String hostname();
#DefaultValue("42")
int maxThreads();
#DefaultValue("1.0")
String version();
}
Then you use it like this:
public class MyApp {
private static ServerConfig cfg = ConfigFactory.create(ServerConfig.class);
private MainWindow window;
public MyApp() {
// you can pass the cfg object as dependency, example:
window = new MainWindow(cfg);
}
public void start() {
window.show();
}
public static void main(String[] args) {
// you can use it directly, example:
System.out.println("MyApp version " + cfg.version() + " copyright (c) ACME corp.");
MyApp app = new MyApp();
app.start();
}
}
You can define the cfg object as member instance on the classes where you need, or you can pass the instance to constructors and methods where you need it.
Version 1.0.4 will be released soon and it will include also "hot reload" and many improvements.

JTest 9.5. How to execute preparation actions before each unit test

I'm using JTest 9.5. I wanted to ask whether there is possibility to perform same preparation routine before each unit test, just like I did it in JUnit with #Before and #After annotations? If yes, then how? Let's say I have following unit test class in JTest:
public class TestArrayFileManager extends PackageTestCase {
FileManager fileMngr;
public TestArrayFileManager(String name)
{
super(name);
}
public Class getTestedClass()
{
return FileManager.class;
}
public void testFileManager1() throws Throwable
{
final String fileName = "InputFile.txt";
fileMngr = new FileManager(fileName);
fileMngr.doResetFile();
fileMngr.doReplaceNthElement(0, 3);
fileMngr.doReplaceNthElement(1, 9);
assertEquals(3, fileMngr.doReadNthElement(0L));
}
public void testFileManager2() throws Throwable
{
final String fileName = "InputFile.txt";
fileMngr = new FileManager(fileName);
fileMngr.doResetFile();
fileMngr.doReplaceNthElement(0, 3);
fileMngr.doReplaceNthElement(1, 9);
assertEquals(9, fileMngr.doReadNthElement(1L));
}
}
Notice how i keep repeating same preparation code. How can I perform it before each test?
JTest complements and extends JUnit which means that it is not there to provide the features of JUnit. You will have to use JTest with Junit in order to achieve what you want.
You can use existing JUnit test cases with JTest which will provide both setUp and tearDown methods using #Before and #After annotations.
If you want to use a JUnit Test Class with Jtest, you need to:
Include the junit.jar file on your CLASSPATH.
Make sure Jtest knows how to locate the Test Class (as described in Loading Test Classes below).
After you perform these steps, Jtest will use the JUnit Test Class when you run your test in the normal manner.
I just fount the methods I have to add in order to achieve preparation and ending tasks before each unit test. These are the methods I found in generated unit tests file and they are working:
public void setUp() throws Exception {
super.setUp();
/*
* Add any necessary initialization code here (e.g., open a socket).
* Call Repository.putTemporary() to provide initialized instances of
* objects to be used when testing.
*/
// jtest.Repository.putTemporary("name", object);
}
/**
* Used to clean up after the test. This method is called by JUnit after
* each of the tests have been completed.
*
* #see junit.framework.TestCase#tearDown()
* #author Parasoft Jtest 9.5
*/
public void tearDown() throws Exception {
try {
/*
* Add any necessary cleanup code here (e.g., close a socket).
*/
} finally {
super.tearDown();
}
}

Running a Test Suite of the same class but with different initial conditions

In JUnit 4, I am looking to write a test suite that is made up of multiple flavors of the same test case, just with different initial conditions on each one. Here is an example:
import java.io.File;
import org.junit.runner.RunWith;
import org.junit.runners.Suite;
import org.junit.runners.Suite.SuiteClasses;
#RunWith(Suite.class)
#SuiteClasses({MultiInputClientServerIntegrationTest.NormalInput.class,
MultiInputClientServerIntegrationTest.SimulationHashIssue.class})
public class MultiInputClientServerIntegrationTest {
#RunWith(Suite.class)
#SuiteClasses({TestClientServerIntegration.class})
public class NormalInput {}
#RunWith(Suite.class)
#SuiteClasses({TestClientServerIntegration.class})
public class SimulationHashIssue {
public SimulationHashIssue() {
TestClientServerIntegration.simulation = new File("test\\BEECHA01\\sim2.zip");
TestClientServerIntegration.inputFile = "files\\config.in";
}
}
}
As you can see, both inner classes have SuiteClasses of the TestClientServerIntegration.class but the second one is changing some static variable values. I am finding that this constructor never gets called, so these statics never get changed.
My end goal is to run this TestClientServerIntegration.class over and over with multiple types of input. If I can run a test suite this way, that would be ideal -- so hopefully it is possible. I'd like to do as little hacking of JUnit as possible, but what needs to get done will get done.
I solved it! The book JUnit in action helped a lot. Here is my code:
/**
* The Class MultiInputClientServerIntegrationTest.
*/
#RunWith(Suite.class)
#SuiteClasses({MultiInputClientServerIntegrationTest.NormalInput.class,
MultiInputClientServerIntegrationTest.BEECHA01SimulationHashIssue.class})
public class MultiInputClientServerIntegrationTest {
/**
* The Class NormalInput.
*/
#RunWith(Suite.class)
#SuiteClasses({TestClientServerIntegration.class})
public class NormalInput {}
/**
* The Class BEECHA01SimulationHashIssue.
*/
// #RunWith(Suite.class)
#RunWith(InterceptorRunner.class)
#SuiteClasses({TestClientServerIntegration.class})
#InterceptorClasses({BEECHA01SimulationHashIssueInterceptor.class})
public static class BEECHA01SimulationHashIssue extends TestClientServerIntegration { }
/**
* The Class BEECHA01SimulationHashIssueInterceptor.
*/
public static class BEECHA01SimulationHashIssueInterceptor implements Interceptor {
static File sim = new File("test\\BEECHA01\\6dof_Block20_FD2_2.zip");
static String in = "BEECHA01\\config.in";
/*
* (non-Javadoc)
*
* #see test.northgrum.globalhawk.simulation.Interceptor#interceptBefore()
*/
#Override
public void interceptBefore() {
if (!TestClientServerIntegration.simulation.equals(sim)
|| !TestClientServerIntegration.inputFile.equals(in)) {
TestClientServerIntegration.simulation = sim;
TestClientServerIntegration.inputFile = in;
System.out.println("Test set up with BEECHA01 Initial Parameters");
}
}
/*
* (non-Javadoc)
*
* #see test.northgrum.globalhawk.simulation.Interceptor#interceptAfter()
*/
#Override
public void interceptAfter() {}
}
}
Where the special Runners are:
/**
* This interface is used to declare the methods for every interceptor.
*
* #version $Id: Interceptor.java 201 2009-02-15 19:18:09Z paranoid12 $
*/
public interface Interceptor {
/**
* This method will be called before every test - we can implement our own logic in every
* implementation.
*/
public void interceptBefore();
/**
* This method will be called after every test - we can implement our own logic in every
* implementation.
*/
public void interceptAfter();
}
And,
/**
* A custom runner for JUnit4.5 in which we demonstrate the interceptor pattern.
*
* #version $Id: InterceptorRunner.java 201 2009-02-15 19:18:09Z paranoid12 $
*/
public class InterceptorRunner extends BlockJUnit4ClassRunner {
/**
* This is the InterceptorClasses annotation, which serves to hold our interceptor class
* implementations.
*/
#Retention(RetentionPolicy.RUNTIME)
#Target(ElementType.TYPE)
public #interface InterceptorClasses {
/**
* Value.
*
* #return the classes to be run
*/
public Class<?>[] value();
}
/**
* This constructor is a must.
*
* #param clazz the test-case class
* #throws InitializationError the initialization error
*/
public InterceptorRunner(Class<?> clazz) throws InitializationError {
super(clazz);
}
/**
* Override the methodInvoker, so that when it is called we wrap the statement with our own.
*
* #param method the test method
* #param test the test-case
* #return the statement
*/
#Override
public Statement methodInvoker(FrameworkMethod method, Object test) {
InterceptorStatement statement = new InterceptorStatement(super.methodInvoker(method, test));
InterceptorClasses annotation = test.getClass().getAnnotation(InterceptorClasses.class);
Class<?>[] klasez = annotation.value();
try {
for (Class<?> klaz : klasez) {
statement.addInterceptor((Interceptor) klaz.newInstance());
}
} catch (IllegalAccessException ilex) {
ilex.printStackTrace();
} catch (InstantiationException e) {
e.printStackTrace();
}
return statement;
}
}
/**
* A statement for our custom runner.
*
* #version $Id: InterceptorStatement.java 201 2009-02-15 19:18:09Z paranoid12 $
*/
public class InterceptorStatement extends Statement {
/**
* A wrapping invoker that will procede the execution, once we execute our interceptors.
*/
private final Statement invoker;
/**
* A list of interceptors that will be executed before the other statements.
*/
private List<Interceptor> interceptors = new ArrayList<Interceptor>();
/**
* A constructor that takes another invoker to wrap our statement.
*
* #param invoker the invoker
*/
public InterceptorStatement(Statement invoker) {
this.invoker = invoker;
}
/**
* We override this method to call our interceptors, and then evaluate the wrapping invoker.
*
* #throws Throwable the throwable
*/
#Override
public void evaluate() throws Throwable {
for (Interceptor interceptor : interceptors) {
interceptor.interceptBefore();
}
invoker.evaluate();
for (Interceptor interceptor : interceptors) {
interceptor.interceptAfter();
}
}
/**
* Add another interceptor to the list of interceptors we have.
*
* #param interceptor we want to add
*/
public void addInterceptor(Interceptor interceptor) {
interceptors.add(interceptor);
}
}
What helped a lot was actually switching to JUnit 4.10 as it gave a more detailed error message. Anyway the main differences here is that I am having my "custom input" tests extend the actual test. Then I created an interceptor which gets overloads the #Before and #After methods and can alter parameters before each individual #Test.
In truth, I'd prefer something that just overloaded each #BeforeClass but beggars aren't choosers. This is good enough and does the job right. It works with Eclipse. Hopefully I'll run across a hook for #BeforeClass and work that instead.
What about an alternative solution?
1.Use template pattern to extract an abstract test class, and make the initial condition preparement an abstract method.
2.Each test case extends the template and override the implentation of initial condition preparement.
3.Group them all in a test suite.
Oh, keep it simple! Your test class can have
a private method, which actually runs the test, and which has parameters corresponding to the various things you want to change from one test to the next;
several public test methods, each of which just calls the private method, with different parameter values.

Categories