I have process belows :
Service1,Service2,Service3 call method a() of DAO together.
How to find service calling in inside method a()?
Related
I have a service class (named A) which has a method with #Async annotation. This method async from class A, calls another service class (named B) which has the annotation #Transactional(propagation = Propagation.REQUIRED). This class B, calls another service (named C) which also has the very same annotation from class B. And, the class C, calls a method from a repository class.
These sequence is all triggered by a post endpoint with a request body.
Being said, I'm facing an intermittent issue that, sometimes I get the result as expected and sometimes I do not have any result (using exaclty the same request body).
Looking into application's logs, I could see that, when I get no result, the endpoint do not reach the repository class and apparently the thread "dies" in the class A (when the async method is called).
So, my main question is: if I change the type of Propagation from REQUIRED to REQUIRES_NEW in the classe C, it would solve my async problem?
REQUIRED means a transaction will be created before the method is invoked, other nested services with REQUIRED will join this transaction.
REQUIRES_NEW in a nested service will create another transaction which will be independent from the first transaction it (with req_new) could be committed even if the first transaction (req) will be rolled back.
I doubt that the transaction propagation is responsible for the described behaviour ( thread "dies"). I would check the thread pools used for async also that there all invocations run through a proxy.
I'm on learning phase of Spring boot
I've code where its written like below to handle exception in whole application. Not sure how its working, but I have NoDataFoundException class in code and its being used at place where no data found issues are happening.
#ControlAdvice
class ControllerAdvisor {
#ResponseStatus(HttpStatus.BAD_REQUEST)
#ExceptionHandler(NoDataFoundException.class)
#ResponseBody
public ResponseEntity<Object> handleNodataFoundException(
NoDataFoundException ex, WebRequest request) {
Map<String, Object> body = new LinkedHashMap<>();
body.put("timestamp", LocalDateTime.now());
body.put("message", "No cities found");
return new ResponseEntity<>(body, HttpStatus.NOT_FOUND);
}
Want to know, how and when handleNodataFoundException method automatically gets called when NoDataFoundException instance gets created ?
Does spring calls this method handleNodataFoundException on the basis of #ExceptionHandler(NoDataFoundException.class) which is bind to method itself and moreover irrespective of name of the method ?
how spring looks for parameters required for above method ? what if it has more parameters in it ?
This is done by proxying (Proxy.class).
Proxying is a mechanism in which a kind of pseudo class is created dynamically and mimics your own class (same methods) and is used to intercept all the method calls. This way it can act before and after the method calls as it please, and in the middle call the real method that you developed.
When you create a #Service in Spring, or a #Stateless in EJB, you never actually create the instances, you delegate the instance creation on the framework (Spring or EJB). Those frameworks proxy your classes and intercept every call.
In your case, and putting it simple, the proxy has a catch around the real call to your method, that catch captures exceptions, and acts upon the framework configuration built based on all the annotations that you created (#ControlAdvice, #ExceptionHandler and so on). And so it can call the handleNodataFoundException(...) in the cases that you defined with annotations.
Update visualization via stacktrace
For instance, if you have two Spring #Component (or #Service, #Repository or whatever), and one calls the other one in a plain call, and you get an exception, in the stacktrace you see plenty of method calls (involving all kind of different classes) between your two component classes, all those are proxies and framework classes that take care of proxying, invoking, configuration and all the magic that the framework does. And everything is triggered by the proxy of your second component just before calling the real code that you developed, because the first component, at execution time, doesn't really call an instance of your class, but an instance of the proxy of your class that the framework created.
If you run a plain main, with two classes calling one to the other, instantiated by you with new, you will only see 3 lines in the stacktrace, because there the instances are plain instances created by you.
I am building a service with RestAPI's. I want to put a custom annotation as mentioned below.
#CustomAnnnotation
public APIResponse apiMethod(APIRequest request) {
}
Functionality of this custom annotation :
Whenever there is a request to this apiMethod, before the execution of this method , i want to call an API in different server with some of the request parameters from this function. Example mentioned below. Basically for every method invocation i want to call a different server.
Instead of doing this
public APIResponse apiMethod(APIRequest request) {
newServiceClient.newAPI(request.getName())
}
I want to do this functionality by using a custom annotation. I know that i can use interceptors to intercept this request and call the API. Is there any other way ?
Edit :
To summarise this question. There is a method(This might not be API start point. It can also be a normal method in your application) in my java code. Whenever i annotate this method, for every invocation of this method in application, i want do some functionality. I want to have this in annotation because i am thinking of providing a library for this annotation so that any function can be annotated
Say I have a Dropwizard/Jersey resource defined like so:
// Pseudo-code
#Path("/fizz")
#Produces(MediaType.APPLICATION_JSON)
class FizzResource {
FizzDao fizzDao
#GET
List<Fizz> getFizzesByType(#PathParam("type") String type) {
// Do some stuff up here
return fizzDao.getFizzesByType(type)
}
#POST
Widget determineWidgetByFoobaz(#PathParam("foobaz") String foobaz) {
// Do some stuff
List<Fizz> fizzes = getFizzesByType(foobaz.type)
Widget w = new Widget(fizzes, true, blah)
// Do some more stuff
return w
}
}
What happens when I call one endpoint (getFizzesByType) from inside another endpoint (determineWidgetByFoobaz)?
Does the framework know to just make a Java method call? Or is an actual network call (to localhost/loopback/etc.) made? If a network call is made, does the framework provide any way to configure it so that just a local Java method invocation is called instead?
If you access the endpoint as a method (i.e. this.getFizzesByType(type)) then it will be called like any other Java method. If you access it via a URI (e.g. ClientBuilder.newClient().target("http://localhost/fizz/" + type).request().get()) then it will be accessed as a network resource.
The getFizzesByType call inside determineWidgetByFoobaz is just another local method call. There's nothing special in those methods, and you can also call them safely in, let's say, a unit test.
What Jersey does on it's bootstrapping process is to scan for classes annotated with #Path and then bind each method annotated with an HTTP method to it's endpoint (if any). That way, when someone fires a GET to /fizz, in a nutshell Jersey gets a FizzResource instance, call it's getFizzesByType method, serializes the returned object to JSON, creates the appropriate HTTP response and sends it back to the client.
I've got a spring-application (Spring Roo uses Spring MVC) on a Tomcat-server.
There are some java-files inside the application. One contains a main-method.
I'd like to be able to execute this main-method when I call a URL like http://localhost/execute
How can I map this?
First you need to be able to handle http://localhost/execute request. You can use servlet or spring-mvc. I don't know Spring Roo, but it most likely has some mechanism to handle HTTP calls (maybe this will help: Spring MVC /Roo - Request method 'GET' not supported).
Once you are able to run arbitrary code on incoming HTTP request, simply call:
SomeClass.main();
or:
SomeClass.main(arg1, arg2);
insider your servlet/controller/whatever.
Maain is just a regular static method. Just call it: MyClass.main("aaa", "bbb"); where MyClass is the class you want to call, "aaa" and "bbb" are the "command line" parameters.
Morning,
calling a method from a class requires you to instatiate this class (or have it instatiated by Spring) and then to call your main method on that object.
As noted in the comments, since your main-Method is a static method, you can call it just on the class level, like this: MyClass.main(args)
Does that help you?