JavaEE Batch Processing Start Process - java

I want to go throw javaee batch processing, so I create a simple web application where I want to expose a get method for starting a job.
#GET
#Produces(MediaType.APPLICATION_JSON)
public Response helloWorld() {
Hello hello = new Hello();
hello.setMessage("Hello World");
JobOperator jobOperator = getJobOperator();
Long executionId = jobOperator.start("myJob", new Properties());
JobExecution jobExecution = jobOperator.getJobExecution(executionId);
System.out.println(jobExecution.getBatchStatus());
return Response.ok(hello).build();
The rest service is working fine, I am running it on an intellij idea community edition and I am using maven plugin for running it on a tomcat server.
The problem is that the BatchRuntime.getJobOperator() is always returning null. I tried to use only the javaee-api dependecy, but then the BatchRuntime class is not found. After that I added javax.batch-api dependency and after that the class BatchRuntime was found, but getJobOperator() always return null.
Please tell me how can I run a job in order to get more familiarized with batch processing in javaee. I have looked over tutorials, git repo, but I didn't there is no clear way for how to run a xml job.

Tomcat is not a full Java EE server, and does not include JBatch. You should use an application server that is Java EE compliant, e.g. Glassfish/Payara, TomEE, or Wildfly.

Related

How to start a jax-rs server?

I have my endpoints like so:
#Path("/users")
public class Users {
private final SomeDependency dependency
public Users(SomeDependency dependency) {
this.dependency = dependency;
}
#GET
#Path("/{id}")
public Response Get(#PathParam("id") int id) {
User user = this.dependency.get(id);
return Response.ok(user).build();
}
}
Now how do I actually run a server with this endpoint?
I am confused about web servers/applications/servlets, using jersey jetty glassfish or whatever. Also web.xml files? what? ResourceConfigs only accept classes, not their instances. Everything seems to be such a mess.
How can I just do something similar to this?
public static void main(String[] args) throws Exception {
SomeDependency dependency = new SomeDependency();
Users usersEndpoint = new Users(dependency);
Server server = new Server();
server.registerEndpoint(usersEndpoint);
server.start();
}
Server
As far as the server goes, you have two types you have to consider: installed or embedded.
Installed
An installed server is one that is installed on your machine. For example, if you download Tomcat 10 and then follow the installation instruction, the server will get installed on your machine at whatever location you choose. In this situation, when you have an app (a war file) you are ready to deploy, you will copy it to your Tomcat server (to a specific location) and on server startup, Tomcat will see the application and then run it. The applications running in this type of environment will require a web.xml as they are deployed in a war file.
Embedded
An embedded server is one that is packaged into your jar application and is started in a main method just like any other Java SE application. Most installed servers also come with an embedded version. All you need to do is add the server dependencies into your application and then write the server configuration and startup (and shutdown) code. Applications running in this environment will not require a web.xml as they are deployed as a jar file.
Which one to use?
With the advancement and popularity of cloud services and microservices, many applications are moving towards embedded servers. The reason is that they are easy to deploy, are scalable, relatively lightweight, and applications become more self contained. There are many other pros that come with using embedded servers, but there are also some cons. Do your research before you make your final decision about which one you should use.
Example
If you want to quickly get started without having to worry about setting up the project, knowing what dependencies you need to add, adding the startup code, an easy way to get up and running is to use a Maven Archetype. If you go to the Jersey Docs, they get you started with an embedded Grizzly server running a Jersey application. What you need to do is run the following command from the command line (assuming you have Maven installed in your machine)
mvn archetype:generate -DarchetypeArtifactId=jersey-quickstart-grizzly2 \
-DarchetypeGroupId=org.glassfish.jersey.archetypes -DinteractiveMode=false \
-DgroupId=com.example -DartifactId=simple-service -Dpackage=com.example \
-DarchetypeVersion=2.33
If you read the docs I linked to, it will give an explanation of all that comes with the initial application. The main class will look like the following (with comments and imports omitted)
public class Main {
public static final String BASE_URI = "http://localhost:8080/myapp/";
public static HttpServer startServer() {
final ResourceConfig rc = new ResourceConfig().packages("org.example");
return GrizzlyHttpServerFactory.createHttpServer(URI.create(BASE_URI), rc);
}
public static void main(String[] args) throws IOException {
final HttpServer server = startServer();
System.out.println(String.format("Jersey app started with WADL available at "
+ "%sapplication.wadl\nHit enter to stop it...", BASE_URI));
System.in.read();
server.stop();
}
}
In this code, they use the packages() method of the ResourceConfig class that specifies a package for Jersey to scan for #Path and #Provider classes to register. In your case, if you don't need that, you can remove the method call. If you want to register your Users instance, all you do is call register(users) on the ResourceConfig.
See Also
What exactly is the ResourceConfig class in Jersey 2 - this link will help you get started with the ResourceConfig class and show you how you can register you resource classes or instances.
Other Frameworks
There are other frameworks out there that you may also want to consider
Dropwizard - Dropwizard is an opinionated framework built on top of Jersey. It uses an embedded Jetty as its server and comes with many other features to make developing your applications easier. They have pretty good, easy to follow documentation. There is a good "getting started" guide if you want to give them a try.
Spring Boot - Spring Boot is a bootstrapping framework that makes getting up and running with applications much easier. There are auto configurations made for you but give you options to change them. You can use Spring MVC or Jersey as the REST framework when you work with Spring Boot. There is also an Initializer, which is similar to the Maven Archetypes, but is interactive and allows you to add what you want to your applications.
So I just accepted the fact that java is an utter mess and pulled these dependencies in:
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-frontend-jaxrs</artifactId>
<version>3.4.2</version>
</dependency>
<dependency>
<groupId>javax.annotation</groupId>
<artifactId>javax.annotation-api</artifactId>
<version>1.2</version>
</dependency>
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-transports-http-jetty</artifactId>
<version>3.4.2</version>
</dependency>
So i can launch everything like so:
public static void main(String[] args) throws Exception {
SomeDependency dependency = new SomeDependency();
Users usersEndpoint = new Users(dependency);
JAXRSServerFactoryBean serverFactory = new JAXRSServerFactoryBean();
serverFactory.setResourceClasses(usersEndpoint.getClass());
serverFactory.setResourceProvider(usersEndpoint.getClass(), new SingletonResourceProvider(usersEndpoint));
serverFactory.setAddress("http://localhost:8080/");
serverFactory.create().start();
}
I have more endpoints, of course, so I put everything in a for loop.
As to why I'm answering from a guest account, the account I used to ask this question was created using a disposable email address, and I can no longer access it.
Hope this helps anyone in the future!

Micronaut 2.0.0 "More than 1 route matched the incoming request"

I'm new to the micronaut framework, and I'm trying to get a simple web-app working. The app has one Controller "TestController", with two GET endpoints; one with a parameter and one without:
#Controller("/api/tests")
public class TestController
#Get
public HttpResponse<String> getAll()
#Get("/{id}")
public HttpResponse<String> getUserProfile(#NotBlank #PathVariable("id") long id)
This is just the class and method sigatures
I've generated the initial application code using the Micronaut Launch web-site (https://micronaut.io/launch/), selecting maven and JDK 1.8.
I compile and run the app using "mvn clean compile exec:exec" or "mvn mn:run".
When I attempt to call the endpoint with no parameters: "GET http://localhost:8080/api/tests"
I get: "More than 1 route matched the incoming request. The following routes matched /api/tests: GET - /api/tests, GET - /api/tests"
When I attempt to call the endpoint with a parameter: GET http://localhost:8080/api/tests/1
I get: "Page Not Found"
I'm running on Windows 10, using eclipse Version: 2019-12 (4.14.0) and JDK version 1.8.0_121-b13.
I've modified the POM to include for various micronaut processors. I've installed m2e in Eclipse and selected "Auto configure JDT APT" for annotation processing.
I would be grateful for any assistance on getting this simple application running. I've uploaded the source to Git Hub on https://github.com/phillwatson/upstart-failures
#JeffScottBrown Thank you for taking the time to look at this. Very much appreciated. Your example led me to the solution, although not quite as simple as using 2.0.0.RC2.
The cause of the issue was my inclusion of the micronauts.jaxrs library. Which, comparing your pom, you didn't have. I'm guessing that the jaxrs annotation processing was causing confusion with the micronaut http annotation. Whatever the underlying cause, removing any reference to jaxrs solved the issue.
Thanks again.

Azure Trigger Function Integration Test With Wiremock

I have an Azure TimerTrigger running (fully functional) with spring boot and am running into an issue running an integration test. Below is what my function looks like.
When I use mvn azure-functions:run I am able to hit http://localhost:7071/admin/functions/myTrigger as defined in the docs
#FunctionName("myTrigger")
public void execute(
#TimerTrigger(name = "timerInfo", schedule = "%myCronSetting%") String timerInfo,
final ExecutionContext context
) {
handleRequest(timerInfo, context);
}
However, I always get 404 responses when running my integration test using wiremock
when().post("/admin/functions/myTrigger").then().log().body().statusCode(202);
I suspect the function itself isn't starting up with spring when running the integration test but that's just a guess. I'm not quite sure how to proceed. I have seen other related answers with C# where they have code to trigger the function inside their test but I cannot find a way to do that in java (nor do I know it that's even possible)

How to enable remote management operations in Wildfly

Trying to read some values from my standalone.xml in Wildfly, I have got the following error message:
{
"outcome" => "failed",
"failure-description" => "WFLYCTL0379: System boot is in process; execution of remote management operations is not currently available"
}
In JBoss 7.1.1 it works fine, please see my java coding inside Ejb Singleton:
#Startup
#Singleton
#ConcurrencyManagement(ConcurrencyManagementType.BEAN)
public class TestBean {
#PostConstruct
private void init() throws Exception {
final ModelNode request = new ModelNode();
request.get(ClientConstants.OP).set("read-resource");
request.get("recursive").set(true);
request.get(ClientConstants.OP_ADDR).add("subsystem", "security");
final ModelControllerClient client = ModelControllerClient.Factory.create(InetAddress.getByName("127.0.0.1"),
9029);
final ModelNode response = client.execute(new OperationBuilder(request).build());
}
}
This error comes at the moment when the client.execute() tries to get ModelNode.
I'd appreciate any help!
Don't know what El Lord Code was trying to accomplish, but in my project, for example, we are using the pattern of Startup Singleton to initialize the application. Now, during that thing, we need to do some programatic login - logout to Wildfly and the logout does some credential cache flushing which depends on acccessing the security domain. The problem is that this whole remote management is not accessible during startup and shutdown (it starts after and ends before the application is started / stopped).
I have posted a similar question here: https://developer.jboss.org/message/944842#944842
The Error is stating that Wildfly is still deploying some WAR/application
In this period the management is still not accessible.
Try to start the Wildfly without any applications in deployment folder and then try to read the standalone config for what ever needs.

What is the best way to write a test case for JERSEY web services?

I have a JAX-RS web service implemented with Jersey library and now I want to test it. In order to do that I'd like to host this service in my test by preinitializing it with mocked services.
What is the best way to host such a service and execute the test calls?
#Path("/srv")
public class MyService
{
#GET
public void action(#Context UriInfo uri)
{ ... }
}
#Test
public void myTest()
{
MyService service = new MyService();
service.setSomething(...);
// How do I host it?
// How do I call it?
}
The new (revised) Jersey Test Framework which is part of the Jersey 1.1.2-ea release now supports the In-Process or In-Memory testing. In order to run your tests in-memory all you have to do is set the property test.containerFactory to com.sun.jersey.test.framework.spi.container.inmemory.InMemoryTestContainerFactory, i.e., run your tests as follows:
mvn clean test -Dtest.containerFactory=com.sun.jersey.test.framework.spi.container.inmemory.InMemoryTestContainerFactory -DenableLogging
For more details please go through the blog entry titled Jersey Test Framework re-visited! at http://blogs.oracle.com/naresh.
I believe the Jersey Test Framework provides a solution for your requirement. It allows you to deploy a single service, and run all its tests. You could use the framework to run your tests against Grizzly Web Container, Embedded GlassFish and/or HTTPServer.
Please note that you could use the framework to run your tests against the regular web containers like GlassFish and Tomcat too. In case you have any more queries please feel free to send me or the Jersey users mailing list - users#jersey.dev.java.net an e-mail.
I haven't tried it, but a JUnit extension like HtmlUnit or HttpUnit may be a good way to test a JAX-RS/Jersey service. The test case can use XPaths to find expected return values and validate the returned value against the expected. See: http://htmlunit.sourceforge.net/gettingStarted.html for more info.
You can use Grizzly to host the services and then use the Jersey Client to access them. Take a look at the sample applications. For example, in the Bookstore sample you may find the TestSupport class and JerseyTest class (found in the jersey-test-framework) of particular interest.
I hope this helps.
(Unfortunately Stack Overflow wouldn't let me post until I removed all the hyperlinks so happy Googling!).
Okay I get it now. Right now the framework doesn't support IN PROCESS, bt we are working on it.
We will see that this support would be added in a coming version of the Jersey Test Framework
Have you looked in to using the Jersey Test Framework? Unfortunately it's still more integration test than unit test, but it might get you on your way.

Categories

Resources