It's been some time since I started noticing that while debugging the application I'm working on, the java debugger randomly steps into some Spring Framework internal methods.
For example, when I add a breakpoint in a RestController endpoint method that calls another service method, the debugger steps into BeanFactoryTransactionAttributeSourceAdvisor.getPointcut() method.
This behavior makes me upset because the only way to avoid this is to add a breakpoint in the service method.
Does anyone know why this happens?
I'm using Intellij IDEA 2020.3 , Java 8 and Spring Boot 2.X if this helps.
Some classes in Spring are enhanced with aspects to provide orthogonal functionality (in this case: transactions, which probably means you annotated your method or class with #Transactional).
At run time (or compile time) additional code is weaved around your own code to provide that functionality (start transaction before running your code, committing on successful completion, or rolling back for (some) exceptions).
In other words, when your code runs, there is more code than just your own, and when you step through the debugger, IntelliJ will step through that code as well and show it to you.
Related
I have an old application (simple Java files starting from main() method) that is called by 4-5 autosys jobs all at same time passing different arguments.
Now, I have refactored this app to use spring boot CommandLineRunner. I changed only starting file to use spring boot to upgrade it.
Question: will this create any problem if my autosys job call this app 5 times at the same time passing different params ? Any issue with conflict of thread execution or object or any other?
I could not find my answer anywhere..though As far I know, all these 5 calls should create different JVM and execute the spring bean from CommandLineRunner. They should be treated all separate...
The call from autosys is simple
“Java -jar javaApp.jar arg1 arg2”
need your expertise suggestion.
Quick help is appreciated.
If you have created different CommandLineRunner classes in your Spring app, then Spring runs them sequentially in the main thread. No additional threads are involved. The runners are run as just about the last step in the initialization of the app. I happen to know this because it recently mattered to what I was doing, and so I looked at the source code.
To see this all for yourself, all you have to do is put a breakpoint at the start of one of your runners, and then look up the call stack. You'll see the loop over the runners directly above you, and you'll see that the bottom of the stack contains your app's main(). Unlike many adventures into the Spring source code, this one was very simple. I recommend you do this if you can just to see how remarkably simple it is.
The above being the case, it sounds like there's no real difference between what you have with Spring and what you had before...other than, of course, changes you've made yourself to your logic. Spring doesn't add any complexity here.
As #MrR says, the only issue you might have is with contention for external resources if you're running multiple copies of your app at the same time. But you would have had those with the old code as well. Spring doesn't introduce anything new here either.
We are currently improving the test coverage of a set of database-backed applications (or 'services') we are running by introducing functional tests. For me, functional tests treat the system under test (SUT) as a black box and test it through its public interface (be it a Web interface, REST, or our potential adventure into the messaging realm using AMQP).
For that, the test cases either A) bootstrap an instance of the application or B) use an instance that is already running.
The A version allows for test cases to easily test the current version of the system through the test phase of a build tool or inside a CI job. That is what e.g. the Grails functional test phase is for. Or Maven could be set up to do this.
The B version requires the system to already run but the system could be inside (or at least closer to) a production environment. Grails can do this through the -baseUrl option when executing functional tests.
What now puzzles me is how to achieve a required state of the service prior to the execution of every test case?
If I e.g. want to test a REST interface that does basic CRUD, how do I create an entity in the database so that I can test the HTTP GET for it?
I see different possibilities:
Using the same API (e.g. HTTP POST) to create the entity. Downside: Changing the creation method breaks two test cases. Furthermore, there might not be a creation method for all APIs.
Adding an additional CRUD API for testing and only activating that in non-production environments. That API is then used for testing. Downside: adds additional code to the production system, API logic might not be trivial, e.g. creation of complex entity graphs (through aggregation/composition), and we need to make sure the API is not activated for production.
Basically the same approach is followed by the Grails Remote Control plugin. It allows you to "grab into your application" and invoke arbitrary code through serialisation. Downside: Feels "brittle". There might be similar mechanisms for different languages/frameworks (this question is not Grails specific).
Directly accessing the relational database and creating/deleting content, e.g. using DbUnit or just manually creating entities through JDBC. Downside: you duplicate creation/deletion logic and/or ORM inside the test case. Refactoring the DB breaks the test case though the SUT still works.
Besides these possibilities, Grails when using the (-inline) option for functional tests allows accessing Spring services (since the application instance is run inside the same JVM as the test case). Same applies for Spring Boot "integration tests". But I cannot run the tests against an already running application version (as described as option B above).
So how do you do that? Did I miss any option for that?
Also, how do you guarantee that each test case cleans up after itself properly so that the next test case sees the SUT in the same state?
as with unit testing you want to have a "clean" database before you run a functional test. You will need some setup/teardown functionality to bring the database into a defined state.
easiest/fastest solution to clean the database is to delete all content with an sql script. (For debugging it is also useful to run this in the test setup to keep the state of the database after a test failure.) This can be maintained manually (it just contains delete <table> statements). If your database changes often you could try to generate the clean script (disable foreign keys (to avoid ordering problem), delete tables).
to generate test data you can use an sql script too but that will be hard to maintain, or create it by code. The code can be placed in ordinary Services. If you don't need real production data the build-test-data plugin is a great help at simplifying test data creation. If you are on the code side it also makes sense to re-use the production code to create test data to avoid duplication.
to call the test data setup simply use remote-control. I don't think it is more brittle than all the http & ajax stuff ;-). Since we now have all the creation code in a service the only thing you need to call with remote control is the Service that does create the data. It does not have to get more complicated than remote { ctx.testDataService.setupDataForXyz() }. If it is that simple you can even drop remote-control and use a controller/action to run it.
do not test too much detail with functional tests to make it not more complicated as it already is. :)
I am working on a project of java. I opened the project in debugging mode, and goes through the program. One thing where I got stuck is that, if I step into a specfic function, it dont go into it. Instead if I put a breakpoint inside that function then program goes upto that point. I am using Eclipse 3.7.2. I dont know why eclipse is showing such a behaviour. Any help will be appreciaed.
dystroy already said in a comment what I was planning to say in this answer: the most common cause for me experiencing this is when the actual runtime class instance is a dynamic proxy, usually from either hibernate, or Spring, or a mock object framework (when testing) such as Mockito. In those cases, you generally have to do exactly what you have done, and put a breakpoint inside the method being stepped into.
Have you heard of any library which would allow me to set up tracing for specific methods at runtime?
Instead of adding (and removing) lots of System.out.println in my code (and having to re-compile and re-deploy) I would like to have a magic thing which would print out a line for each call of selected method without any change in the code. This would work without re-compiling, so some kind of JVM agent (or some non-standard JVM would be needed?). Sounds like a job for aspect programming?
A typical scenario would be to start an application, configure the traced methods dynamically (in a separate file or similar) and then everytime a selected method is called a line with its name (and arguments) is printed out to System.out (or some log file).
Naturally one could think of tens of additional features, but this basic set would be a great tool. BTW, I use Eclipse interactive debugger too, not only the System.out tracing technique, but both have some advantages and sometimes Eclipse is not enough.
Yes what you are referring to is known as Aspect oriented programming. A typical library providing this for Java is AspectJ. You define what are called pointcuts, essentially regular expressions for classes and method names, including wildcards, and the code to execute at each pointcut, known as an advice. This is useful for logging and also security checks and similar cross cutting concerns.
You can turn pointcut advices on and off through configuration. You can have an advice execute before a method call, after it returns or even after it throws an exception. Arguments are also available.
An aspectj java agent is needed for this to work.
In my experience, that kind of very detailed tracing (much more detailed than one would normally use for logging) as a debugging technique is indicative of insufficient unit testing and integration testing.
You can do this using a tool called InTrace.
NOTE: InTrace is a free and open source tool which I have written.
Log4J useful for disabling logging depending on "log-level" (DEBUG, INFO, WARN, FATAL).
You specify in configuration file what the least level you want to appear in logs, e.g., don't log anything below INFO level, and voila!
Looks like there's yet another solution - called Byteman. In their own words:
Byteman is a tool which simplifies tracing and testing of Java
programs. Byteman allows you to insert extra Java code into your
application, either as it is loaded during JVM startup or even after
it has already started running. The injected code is allowed to access
any of your data and call any application methods, including where
they are private. You can inject code almost anywhere you want and
there is no need to prepare the original source code in advance nor do
you have to recompile, repackage or redeploy your application. In fact
you can remove injected code and reinstall different code while the
application continues to execute.
Jackplay is the tool you are looking for.
It allows you to enable logging on method entry and exit points without any coding or redeployment.
It also allows redefining a method body. It gives you web based UI as control panel to enable or undo tracing on your class.methods.
I'm working on modifying an existing application implemented as a 2.1 stateless EJB. I'd like to put in some kind of generic, detailed, logging of all calls made to the EJB.
Stuff I'd like to log:
Name of method being called
Serialized copy of all passed parameters
Serialized copy of return value
I implemented something like that for an asp.net REST web service before by simply putting in a hook before the request is processed and one right before the response is sent back. It produces a lot of data, but it's well worth it for debugging a long running system.
I'm not sure how the same can be done for an EJB. I'd like to avoid AOP since the application doesn't currently use AOP. Interceptors won't work because it's not EJB 3.0.
Does anyone know of a way to hook into the EJB processing pipeline to look at request as they come in? Is there another approach to doing this?
Thanks
I think there are only two ways two ways to know when a method of an EJB (or any other class) is called:
Bad solution: using the Java Debug Interface (JDI) you can know which line is executed, as you know it when you are debugging Java with your IDE. It's complicated and there are some problems when you are debugging an application in the same JVM where JDI runs.
Good solution: as Thomas Owens says, AOP is the recommended solution. If you are not using it in your project now, this is a good reason for using it.