I want to able to have a client/server application which can perform the following:
Have client send "java task instructions" (ex. name of method, class to run or app to execute) to a remote server
server receives the task execution details and launches a new JVM and loads the classpath etc...
server executes the task
server stores the task response in a cache
shuts down the new JVM
server continues to wait for further executable task details which could reference object in cache by name
What is the best APIs to implement this in Java if I don't want to use RMI?
Do I want to establish a connection by using a socket or is there an easier API?
From what I know, correct me if im wrong, I cannot use ProcessBuilder to execute a static method or to get a response.
thanks in advance
UPDATE
I am new to threads and RMI, so how would I then make it so that when client gets the factory stub to creates a new object which will contain the behavior actually needed to execute a task on the server, that the object code is executing in its own thread?
I want this behavior so that two different clients are executing two different tasks at the same time in different threads without reusing the same remote object instance. Here is some simple sample code to help explain what I want
Factor Interface
public interface Factory extends Remote
{
public Executor create() throws RemoteException;
}
Factory implementation
public class FactoryImpl implements Factory
{
public FactoryImpl()
{}
#Override
public Executor create() throws RemoteException
{
//create a new executor in another thread
}
}
Executor interface
public interface Executor extends Runnable, Remote
{
public String executeTask(String pClass, String pMethod, List<String> arguments) throws RemoteException;
}
Do I just want to create/start a new Runnable class that instantiates the executor object?
Related
I have a case to be implemented in my project.Below is a sample rest service which has to be implemented
#GET
#Path("/test/{id}")
#Consumes(MediaType.APPLICATION_JSON)
#Produces(MediaType.APPLICATION_JSON)
public String getData(#PathParam("id") String id) {
//Some processing to get value of String
String result = doSomeProcessing();
//I want to return this result to GUI and call one more rest api
// and end this process without waiting for response from second
//call
new Thread(){
//call second rest api
}.start();
return result;
}
Is this good approach using new Thread to call second rest API and return result without waiting for response from second rest API ?
I have also looked into Asynchronous Rest call, but it doesn't exactly suit my requirement. Please advice. Thanks in Advance
Avoid starting Threads directly. Consider an ExecutorService instead as shown below:
#Singleton
#Path("foo")
public class FooResource {
private ExecutorService executor;
#PostConstruct
public void onCreate() {
// Creates a thread pool that reuses a fixed number
// of threads operating off a shared unbounded queue
this.executor = Executors.newFixedThreadPool​(10);
}
#GET
public Response getFoo() {
String result = doSomeProcessing();
// Submits a Runnable task for execution
executor.submit(new LongRunningTask());
return Response.ok(result).build();
}
#PreDestroy
public void onDestroy() {
// Initiates an orderly shutdown in which previously submitted
// tasks are executed, but no new tasks will be accepted.
this.executor.shutdownNow();
}
}
public class LongRunningTask implements Runnable {
#Override
public void run() {
try {
// Simulate a long running task
// Don't do it in a real application
Thread.sleep(10000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
Explore the Executors API for details on how to create an ExecutorService instance.
In Java SE and in a Servlet container, you can use an ExecutorService for your long running task. In a Java EE container, you should use a ManagedExecutorService instead:
#Resource
ManagedExecutorService executor;
Once it's a resource managed by the container, you don't need to instantiate and dispose it manually.
I not sure what do you exactly mean by "calling the second REST API" so I assume that you're sending an HTTP request to another external API, i.e "second REST API".
You can use Apache HC to send the request and skip waiting for the response. See its fluent API which is easy to use. Async.execute is the one that ought to be used in your case. The Async class uses a thread-pool underneath to handle background requests.
I should mention that I haven't used any other HTTP client libraries. There might be other choices out there with almost the same functionality.
Side Note I strongly suggest ExecutorService, esp. ThreadPoolExecutor instead of creating new threads. It has more control over life-cycle of threads and manages system resource efficiently. ExecutorService has methods for fire and forget scenarios (submit). However, this only makes sense when your "second REST API" call is actually implemented in another method in your application and lives within the same JRE.
I'd say yes and no; there is nothing "wrong" about calling another service asynchronously (ex: a metrics subsystem to register that a call to that service was made). However, I wouldn't create threads straight in the getData method, I would use another (injected) object to hide the implementation detail (ex: just calling some sort of myOtherService.submit(something). That way you can easily switch from something synchronous, to asnychronous and even change the async method to your liking.
As to the actual implementation, instead of creating threads, I would submit callables to an executor service instead so you save the overhead of creating actual system threads, or you could even have one or more threads waiting on a blocking queue and just put jobs in that queue for threads to pick them up.
I am using CXF to call web service. It is used in a simple way like it is described in the documentation:
HelloService service = new HelloService();
Hello client = service.getHelloHttpPort();
String result = client.sayHi("Joe");
How can I terminate this service call when it takes time?
I found only one related question but this doesn't provide any solution.
How to terminate CXF webservice call within Callable upon Future cancellation
I think this is more of a function of the web server. For example, if you use Jetty to serve your CXF content, then you can set the thread pool to something that'll watch your threads.
ThreadPoolExecutor pool = new ThreadPoolExecutor(...);
ExecutorService svc = new ControlledExecutorService(pool);
server.setThreadPool(new org.eclipse.jetty.util.thread.ExecutorThreadPool(svc));
Then for the custom executor service (sorry, all code typed in the browser directly. I'm on an iPad with no Java. So you'll likely need to make slight adjustments, but the useful parts should be here):
public class ControlledExecutorService implements ExecutorService {
private ExecutorService es;
public ControlledExecutorService(ExecutorService wrapped) {
es = wrapped;
}
#Override
public void execute(final Runnable command) {
Future<Boolean> future = submit(new Callable< Boolean >() {
public Boolean call() throws Exception {
command.run();
return true;
}
});
// Do the proper monitoring of your Future and interrupt it
// using Future.cancel(true) if you need to.
}
}
Be sure to pass true to cancel() so that it sends the interrupt.
Also remember than just like with any thread, just because you send it an interrupt, it doesn't mean it'll comply. You have to do some work in your threads to make sure they're well behaved. Notably, periodically check Thread.currentThread().isInterrupted() and properly handling InterruptedException to pick it up and stop the task gracefully instead of just letting the exception blow everything up.
I'm new to Vert.x and I'm a little bit confused with how to run\deploy Vert.x app.
I'm used to write a server by having a main class with static main() method which there performs all my initial startup code, like: connecting to DB, reading configuration files, initializing internal services and eventually creating the listening socket for accepting new connections.
For example:
public class Server {
public static void main(String args[]) {
Server server = new Server();
server.run();
}
public void run() {
// load configuration
....
// Connect to DB
....
// Initialize internal services
....
// Create listening socket on server port
...
// and more...
}
now to my question:
Vert.x forces me to make my main class extends Verticle class and override start() method
to initialize the listening socket.
so now all my initialization process must be done inside this start() method.
Does this make sense??
and I can never run my application via command line like I'm used to but rather use the "vertex" app
Am I missing something??
Yes, you are correct. A vertx app is nothing but a set of verticles running inside vertx instances.
If you want your app to have main method as usual then you can use vertx as embedded mode i.e inside your main method you start a vertx instance using the API and then start verticles inside that instance.
Check out embedding guide at: https://vertx.io/vertx2/embedding_manual.html
I am developing a TCPIP application where the client will send information to a specified port and the server will listen to that port. I would like to achieve the following:
Reconnect to the the client/port to see whether it is active after a specified time period.
I have the below code implemented:
#Stateless
#Local
public Listener implements ConnectionListener {
public void listen() throws Exception {
ServerSocket serverSocket = new ServerSocket(somePort);
Socket socket = serverSocket.accept();
while(!socket.isClosed()) {
}
}
}
public interface ConnectionListener {
public void listen() throws Exception;
}
How can this be achived with EJB technology? I know the while loop is wrong but what can be included. I have two approaches:
Wait for a time period to reconnect
Thread
However, I do not wish to use the Thread appraoch.
I know in EJB there are things such as an EJBTimer. What would be the best way to implement this and how could this be implemented in the code. Could you help how I could change the while loop to do what I want it to do?
Also, the client has no API to call on this application. How can this instance be triggered on start up of the Application Server so that messages are listened to. Usually, this could be achieved through a Servlet but I don't think this will work. Any ideas?
This kind of functionality is at the "edge" of the types of things you would do in EJB. typically, EJBs do not directly do network type activity, especially long term listening.
what you really want is an EJB singleton. this is kind of like a standalone instance which can do more advanced things like custom concurrency/threading and (relevant to you) start a custom socket listener.
I am trying to test Cassandra with JUnit External resources. I have two classes CassandraExternalResource and TestCassandra. Here is snippet from TestCassandra:
public class TestCassandra {
#Rule
public CassandraExternalResource cassandraExternalResource = new CassandraExternalResource();
#Test
public void test() throws InterruptedException {
System.out.println("During Test");
}
}
In before method of CassandraExternalResource I start Cassandra Server with a separate thread. What I want is to make test cases wait until cassandra server is up and running.
Since server takes some time to start, test cases start to run before server is ready.
Any help is appreciated.
You can extend the rule's before method by pinging the cassandra server until it is ready.