My application is a standalone Java Application which uses Spring IoC. Bootstraping the application with ApplicationContext loads lets say 35 services in memory which are then used through out the JVM lifecycle instance of my application. This bootstraping requires about 6-7 minutes, which makes unit testing difficult.
This is the sequence of steps I have to do, which I am trying to avoid and still use Spring:
Bootstrap (Spring) and then actual business logic code.
Test code.
After testing I find something I want to change, which means I have to stop JVM, modify my code, start it up again, at this point Spring again takes about 6-7 minutes bootstraping the application.
How can test my modified code in the same JVM instance without being forced to restart the JVM?
There is no easy solution to this
I know three possible ways to avoid your problem:
Try mocking parts of your services. Especially on junit tests this is recommended praxis. In IOC ready architecture it should be easy. On manual testing you can use fake services.
Switch to OSgI architecture. This will allow you to start, stop and redeploy single services. But you will have to use an OSgI container and it will take a multiple of 6-7 minutes to switch.
Try something like JRebel which promises to eliminate problems of hot deployment (after 14 days evaluation you will have to buy it). But many times extended hot deploment wont help because you will have to clean up your application context.
Related
Is it possible to substitute default Spring Framework's way of creating and managing objects via reflections with other dependency injection tool (that would be faster, because would avoid reflections), while still holding on Spring's rich API?
For example, I would like to have beans created by Dagger 2 or Tiger or Feather that would still be able to interact with Spring Data/Social/MVC.
https://github.com/google/dagger
https://github.com/google/tiger
https://github.com/zsoltherpai/feather
I know that someone is going to say "start worrying about performance when it will become problem" - well, I would say it's about time to start worrying about it right now.
In my option, it would allow Spring to embrace FaaS (Function as a Service). FaaS jvm is going to be shut down after serving it's call, so You either keep it running (like regular server) and pay for literally every millisecond or some calls may be delayed even few seconds (to boot everything up).
I have found two projects, that are trying to use Spring in FaaS environment and are tackling this problem, but in my option it's easier to remove problem (reflections) that try to overcome it with hacks.
https://github.com/markfisher/spring-cloud-function
https://github.com/kennyk65/spring-cloud-serverless
Or, maybe there is another way to solve this problem and efficiently use Spring in FaaS, that I am not aware of?
Related question: Running Spring Boot on Amazon Lambda
I have been trying to use minimal Spring Framework application (like 3-5 classes) and still it takes (sometimes) 5-15 seconds to handle first request (next are handled in 50-100ms), so minimizing isn't really working in this case.
I'm in the same boat, trying to finding a FaaS friendly DI framework for JVM. Since nothing can beat Spring ecosystem on JVM, it would be great if Spring had reflection-less mechanism and compile time DI. I could not find much on that front though.
Micronaut solves the exact same problem and looks interesting. It has an adapter layer for spring annotations. Micronaut is purpose built for faster start-ups using compile time DI.
Of course, this is good for newer applications but not for very large applications with lots of existing spring code-base.
Today, spring-fu could be an option to create spring application reflection-less approach.
According to its documentation:
Spring Fu is an incubator for JaFu (Java DSL) and KoFu (Kotlin DSL) designed to configure Spring Boot explicitly with code in a declarative way with great discoverability thanks to auto-complete. It provides fast startup (40% faster than regular auto-configuration on a minimal Spring MVC app), low memory consumption and is a good fit with GraalVM native thanks to its (almost) reflection-less approach.
Note: spring-fu is not supposed to be used in production.
The application I am currently working with is being worked on by 3 separate teams, each working away on different functional areas that come together at the end of the day. The difficulty is keeping the 3 teams always in sync and not having one team's issues affect another. I am looking for a way that I can stub out / mock the calls that are being made to some of these services provided by the other teams so that we can work separately most of the time, yet quickly switch back to integrated mode when needed.
Ideally I would like:
- during normal development, I could turn on a flag and those services will be mock services (for example, when I am just developing away on my part of the code and don't really care if the other team's service returns the right thing, just that it returns something)
- I don't want to have add code to check this flag everywhere in the code and if it is on, use the mock, else use the real thing... I just want it to automatically know to use the mock class when this flag is on
We are using Java 7 + CDI + Jboss. Is this possible to do with some kind of wiring or filters?
TIA.
Using Alternatives you can achieve this better ways, you can switch back to integrated mode when needed with disable alternative in beans.xml
CDI Alternatives are so good for the Mock service.
Instead of having to change the source code of your application, however, you can make the choice at deployment time by using alternatives.
Alternatives are commonly used for purposes like the following:
To handle client-specific business logic that is determined at runtime
To specify beans that are valid for a particular deployment scenario
(for example, when country-specific sales tax laws require
country-specific sales tax business logic)
To create dummy (mock) versions of beans to be used for testing
Alternatives allow you to overwrite this at execution time using the beans.xml file - a simple deployment artifact.
A typical scenario would be to use different beans.xml for different environments and thereby enable mock-alternatives for components that you don't want to execute on your local / integration environments.
Using Alternatives in CDI Applications
In Spring-based applications (using dependency injection), I've accomplished this by keeping two application contexts, one configured to use stubs and one configured to use real code. I wrote some wrapper code to load the appropriate application context at the right time, but you could manage it other ways, i.e. with separate run targets that use a different classpath.
In terms of the stubs, I've often created them by hand (i.e. written stubbed services that wrap a spreadsheet of canned data or generate random data), but Mockito could be useful when building certain kinds of stubs.
Depending on what kinds of resources you need to stub (and whether you have a budget), another option is service virtualization. I don't have any direct experience using service virtualization tools, but my current client is using the commercial LISA tool to stub out a SOA service layer. I gather that several companies sell similar tools.
I'm working on a project at work that runs on the spring framework and requires a connection to an oracle database at all times. When I want to test a new method I have to stop my server, rebuild, start the server, then launch my application.
My question is is there any way to run my application without having to launch it every time? I'm okay with having to restart the server but I'm trying to eliminate launching the application every time.
Cheers.
What you seek are integration tests. You need to break your application into individual pieces and test their functionality against the oracle database bit by bit. These little pieces can be tested by certain testing technologies such as the popular JUnit.
All the pieces that you need should only depend on the data source and whatever other collaborating beans that are needed. Break your bean definitions apart such that they are small and only depend on very few beans, tracking back to the data source bean. You can then use JUnit (or whatever testing technology you'd like) and Spring's testing annotations to make small application contexts
See this section of the Spring reference manual for more information:
http://static.springsource.org/spring/docs/current/spring-framework-reference/html/testing.html
When you have tests, you don't actually run the application - you run a part of it to verify its behavior individually. You can then add tests that test the pieces together, and eventually your confidence in the application will rise.
I am a little confused about integration testing of a simple EJB. If I want to test the EJB's local interface/no-interface do I need to use Arquillian? I stumbled upon Arquillian but I have never used it. I have a Maven directory structure/Glassfish and Eclipse Indigo
If I want to test the EJB's local interface/no-interface do I need to use Arquillian?
It is not necessary to use Arquillian, but there are certain things made easier when you do so.
Ordinarily, you would merely use the EJBContainer API available in EJB 3.1 for testing of EJBs in an embedded container (that runs in the same JVM as the tests). In the case of embedded Glassfish, this typically results in deployment of EJBs that are found in the classpath of the application.
Arquillian allows you to do a lot more than execute tests in a container. It manages the lifecycle of the container, thus not requiring any writing of code beyond setting the properties in the arquillian.xml file. It allows you to manage deployments to a container in a far more easier manner; using the ShrinkWrap API, one can programmatically perform different context-sensitive deployments to a container. Furthermore, injection of dependencies (test enrichment) can also be performed, so long as they're supported by Arquillian.
It would suffice to know that the embedded Glassfish container support for Arquillian, uses the same APIs that are exposed by the embedded Glassfish API; usually you might end up duplicating the work of Arquillian, except in certain unique scenarios.
If you're interested in taking a look at examples using Arquillian, this GitHub project would help.
If you use j2ee 6, you can use EJBContainer to create full ejb instanse.
http://download.oracle.com/javaee/6/api/javax/ejb/embeddable/EJBContainer.html
http://download.oracle.com/javaee/6/tutorial/doc/gkcrr.html
When you are not a fan of mocking (just like me), then you could either have a look at ejb3unit (http://ejb3unit.sourceforge.net/), or try Arquillian.
I must say I had very good experiences with "ejb3unit".
But it seems that "EJB3unit" peoject was not maintenance since 2-3 years. But supprisingly, weeks ago, there are again some activities on the ejb3unit site.
Arquillian is not so easy start with. I would say this mainly lies in the documentation, missing running examples, and good turorials.
But so long as you have made your firt Arquillian test run, Arquillian begins to shine!
Under the following link, you could find a tutorial serial on step by step setting up Arquillian:
http://milestonenext.blogspot.de/2012/12/ejb3-integration-test-with-arquillian.html
At work we are trying to simplify an application that was coded with an overkill use of Spring Remoting. This is how it works today:
(Controllers) Spring MVC -> Spring Remoting -> Hibernate
Everything is deployed in a single machine, Spring Remoting is not needed (never will be needed) and adds complexity to code maintenance. We want it out.
How to ensure everything works after our changes? Today we have 0% code coverage! We thought on creating integration tests to our controllers so when we remove Spring Remoting they should behave exactly the same. We thought on using a mix of Spring Test framework in conjunction with DBUnit to bring up Oracle up to a known state every test cycle.
Has anyone tried a similar solution? What are the drawbacks? Would you suggest any better alternative?
It always depends on the ratio effort / benefit that you are willing to take. You can get an almost 100% code coverage if you are really diligent and thorough. But that might be overkill too, especially when it comes to maintaining those tests. But your idea is good. I've done this a couple of times before with medium applications. This is what you should do:
Be sure that you have a well known test data set in the database at the beginning of every test in the test suite (you mentioned that yourself)
Since you're using Hibernate, you might also try using HSQLDB as a substitute for Oracle. That way, your tests will run a lot faster.
Create lots of independent little test cases covering most of your most valued functionality. You can always allow yourself to have some minor bugs in some remote and unimportant corners of the application.
Make sure those test cases all run before the refactoring.
Make sure you have a reference system that will not be touched by the refactoring, in order to be able to add new test cases, in case you think of something only later
Start refactoring, and while refactoring run all relevant tests that could be broken by the current refactoring step. Run the complete test suite once a night using tools such as jenkins.
That should work. If your application is a web application, then I can only recommend selenium. It has a nice jenkins integration and you can create hundreds of test cases by just clicking through your application in the browser (those clicks are recorded and a Java/Groovy/other language test script is generated).
In our Spring MVC / Hibernate (using v3.4) web app we use an Oracle database for integration testing.
To ensure that our database is in a known state each time the test suites are run, we set the following property in our test suite's persistence.xml:
<property name="hibernate.hbm2ddl.auto" value="create"/>
This ensures that the db schema is created each time our tests are run based on the Hibernate annotations in our classes. To populate our database with a know data set, we added a file named import.sql to our classpath with the appropriate SQL inserts. If you have the above property set, Hibernate will run the statements in import.sql on your database after creating the schema.