I have couple of beans defined in the applicationContext.xml file and found if I made mistake(say typo) with the bean's name, spring won't complain anything and go ahead load the invalidate configuration. doesn't spring do the checking automatically? and how can i implement schema validation on the applicationContext.xml file? thanks.
IntelliJ IDEA has a wonderful support for Spring, including:
detecting broken references (bean does not exist, has a wrong type, etc.)
completing bean names when Ctrl+Space is pressed (along with narrowing the list to only the beans matching by type)
discovering missing/duplicated beans when #Resource/#Autowired is used and it will fail to autowire at runtime
quick navigation between Java and application context XML
...and lots more
Also I strongly recommend writing Spring smoke integration test. It doesn't have to test anything, just context startup (you would be amazed, how many errors it discovers).
To avoid errors in spring context I suggest you to use a plugin which checks its contents, for instance springIDE or SpringSource Tool Suite. In this way the plugin validates your spring contexts during development and you can find errors before the execution of your application.
in addition to this problem , i had problems with detecting duplicate bean ids that would get overridden unintentionally among others but finally i found this open-source project that helps you write JUnit unit tests that going to detect these problems. it was very easy to use and solved my problemsm it's called Beanoh
Related
I'm working in a webapp and this is the first time that I'm using Java based configuration. I have a bunch of class to configure all:
ApplicationContext
PersistenceContext
SecurityContext
WebAppInitializer
WebMvcContext
Now I'm defining Spring Data repositories and the service layer so I need to inject the repositories there. Normally I would use Autowired but I've read that it is preferable to define the injections manually so the question is, where?
Maybe neither of the previous configuration classes is suitable for such task but, do I have to create a single class to define all the injections or is better to have on for each function? What happens if the project grows too much?
I think that the main question would be what is best way to organize dependencies in a Spring project. What do you do?
I add here an image of the structure of the project as a petition. I'm trying to decouple layers and now I need to inject UserRepository to UserService.
No, I would not define a single class to do all the injections. All your classes are coupled that way.
I don't understand what "define the injections manually" means. You have to specify them in either XML or annotations. There's no other way that I know of.
You don't say if you're using XML or annotation configuration. I find myself using the latter more of the time, with only enough XML configuration to tell the Spring app context to scan for annotations.
The Spring idiom would have you specify your configuration in layers if you're using XML. It's a moot point for annotations, because they go into your source code.
Your application will read the Spring context on start up, instantiate all the beans, and wire together the necessary dependencies. You're good to go from then on.
I disagree with the link you provided. Avoid autowiring? No.
The article said that he recommends using XML configuration for large projects. This is a very small project at this point. It seems to me that auto wiring with annotations would be fine even by the article's author's words.
I recently started as a freelancer on my current project. One of the thing I threw myself on, was the failing Jenkins build (it was failing starting from April 8th, a week before I started here).
Generally speaking, you could see a buttload of DI issues in the log. First thing I did, was get all tests to work in the same way, starting from the same application context.
They also implemented their own "mocking" thing, which seemed to fail to work correctly. After a discussion with the lead dev, I suggested to start using Springockito. (for a certain module, they needed mocking for their integration testing -- legacy reasons, which can't be changed)
Anyway, stuff started failing badly after that. A lot of beans which were mocked in the test, simply weren't mocked, or weren't found or whatever. Typically, it would fail on the loading of the application context, stating that one or another bean was missing.
I tried different stuff and different approaches, but in the end, only the thing I most feared would work: add #DirtiesContext to every single test. Now, the maven build is starting to turn green again, tests start doing what they are supposed to do. But I am reloading the Spring context each and every time, which takes time - which is all relative, since the context is loaded in about 1 - 2 seconds.
A side note to this story is that they've upgraded to Hibernate 4, and thus to Spring 3.2. Previously, they were using an older version of Spring 3. All tests were working back then, and the #DirtiesContext thing was not necessary.
Now, what worries me the most, is that I can't immediately think of an explanation for this weird behaviour. It almost seems that Springs context is dirtied, simply by launching a test which uses #Autowired beans. Not all tests are using Mocks, so it can't be that.
Does this sound familiar to anyone? Has anyone had the same experiences with integration testing with (the latest version of) Spring?
On Stackoverflow, I've found this ticket: How can a test 'dirty' a spring application context?
It seems to pretty much sum up the behaviour I'm seeing, but the point is that we're autowiring services/repositories/..., and that we don't have any setters on those classes whatsoever.
Any thoughts?
Thanks!
To answer my own question, the secret was in the Spring version. We were using Spring 3.1.3, whereas I presumed they were using Spring 3.2 (they were constantly speaking about a recent upgrade of the Spring version).
The explanation was here, a blog post I stumbled over in my hunt to get it fixed: Spring Framework 3.2 RC1: New Testing Features
And a copy paste of the relevant piece:
The use of generic factory methods in Spring configuration is by no means specific to testing, but generic factory methods such as EasyMock.createMock(MyService.class) or Mockito.mock(MyService.class) are often used to create dynamic mocks for Spring beans in a test application context. For example, prior to Spring Framework 3.2 the following configuration could fail to autowire the OrderRepository into the OrderService. The reason is that, depending on the order in which beans are initialized in the application context, Spring would potentially infer the type of the orderRepository bean to be java.lang.Object instead of com.example.repository.OrderRepository.
So, how did I solve this problem? Well, I did the following steps:
create a new maven module
filter out the tests which needed mocking. All the non-mocked test would run normallly in a Spring build, in a separate Failsafe run (I created a base-package "clean", and sorted them out like that)
Put all the mocked tests in a base package called "mocked", and make an additional run in Failsafe for the mocked tests.
Each mocked test is using Springockito, to create the mocks. I'm also using the Springockito annotations, to easily do a #ReplaceWithMock in place. Every mocked test is then annotated with #DirtiesContext, so the context is dirtied after each test, and the Spring context is reintroduced with each test.
The only reasonable explanation that I could give, is that the context is effectively being dirtied, because there is a framework (Springockito) which is taking over the management of the Spring beans from the Spring framework. I don't know if that's correct, but it's the best explanation I could come up with. That, in fact, is the definition of a dirty context, which is why we need to flag it as dirty.
Using this strategy, I got the build up and running again, and all tests are running ok. It's not perfect, but it's working, and it's consistent.
I'm working on resolving an odd issue I'm having with my project that has cropped up since we've started working on integration testing. What happens is that I use the "jetty-maven-plugin" to startup an instance of the application, once it's started the "maven-failsafe-plugin" starts to run the integration tests. This much is setup and running well.
What I'm trying to do now is this: I'd like to get a handle on my service layer so that I can setup some fixtures for my tests to run against. Up until now, our integration tests have been pretty simple minded and I'd like to turn it up a notch and test the actual filling out of forms and so on. For this to work, I need to be able to setup some fixtures and then remove them so that these test are reproducible. We're running against a test database that we use for just this purpose.
From what I've read, this is not unreasonable. Nonetheless, when I actually run the tests I get a very odd error message and stack trace. From what I can tell, Maven starts up the application in Jetty without issue. Then the failsafe plugin starts running the test and, once it hits the first integration test, it begins instantiating a Spring instance and context. It correctly pulls in it's properties and configuration files but when it tries to actually inject the service object, I am seeing this error:
Caused by: org.springframework.beans.factory.BeanDefinitionSt
oreException: Unexpected exception parsing XML document from class
path resource [app-config.xml]; nested exception is
org.springframework.context.annotation.Conflicting
BeanDefinitionException: Annotation-specified bean name
'pesticideRoleRepositoryImpl' for bean class
[dao.role.PesticideRoleRepositoryImpl] conflicts with existing,
non-compatible bean definition of same name and class
[dao.role.PesticideRoleRepositoryImpl]
I will spare you all the stack trace, I can make it available at any time. ;-)
I started wondering if I was going about this all wrong and so I went back and setup a test project in much the same way. The test project is far simpler and doesn't have this issue. When it runs the integration tests the service objects are injected without issue. If you are interested, you can take a look at my test project on GitHub.
My Question Is This...
Has anyone seen this error before? Could there be some conditions under which Spring will have this kind of problem?
It's clear to me that with this kind of integration testing, I end up with two Spring containers that use the exact same configuration. I thought this might be the problem but the test project works the same way and doesn't have this issue. I'm also troubled by the fact that even though there are two beans with the same name and class, Spring believes that they are incompatible.
Thank you, any help would be greatly appreciated! :-D
This error occurs when two diferent files contains the same class (bean) definition and are incompatibles, ie oldBeanDefintion.equals(newBeanDefinition) == false
You could check:
Why the scanner is loading this class twice.
Why oldBeanDefintion.getSource().equals(newBeanDefinition.getSource()) = false
Why oldBeanDefinition.equals(newBeanDefinition) = false
You could put a break point on ClassPathBeanDefinitionScanner.isCompatible() or extends ClassPathBeanDefinitionScanner and override isCompatible method and log some useful info to find the error.
As last option, XML BeanDefinitions cannot be overriden by scanned ones, so if you define the bean in XML, scanned clases with same bean name will be ignored.
The selected answer was correct, the root problem was that there were multiple instances of the bean being created. Interesting, though, is that the other instances were mock instances; they were being picked up because they were mixed in with the tests and all of the tests were placed in the classpath.
There are likely many solutions, my fix was to add a "context:exclude-filter" to the "context:component-scan" declaration in my application configuration.
I am currently working on a solution for testing EJB 3 Services with JUnit.
(Yes, I have looked at ejb3unit but it doesn't work for me. Yes, I have looked at container-integrated testing with openEJB but that didn't work out neither..)
So my question is what would be the way for resolving #EJB annotated Dependencies? And I don't mean by using a DI Framework like Weld, Guice or Spring. The solution should be applicable for plain old JUnit Tests -> without using an EJB Container like JBoss, Glassfish or openEJB.
I was able to replace the injection of the entity manager via #PersistenceContext with a little hack using java reflections. So how would I do that for dependencies with #EJB annotation?
(I wouldn't mind building and resolving the dependency tree myself, just looking for ideas ;) )
Greetings from Germany,
p.s.
Not sure why you're against the solution you proposed.
I was about to offer stuff like Arquillian, but hey - you don't want to have a container involved.
I just want to be sure about the reason you don't want container, before I move on to some ideas (though I did not test them) -
With JBoss AS 7.x deployment time of enterprise application servers was vastly reduced,
Not to mention that with Arquillian you have a deployment API, and you can decide what you will deploy (i.e - deploy for example just a single bean for a given test).
However, I do respect you question, so here are some ideas -
A. You mentioned you managed to inject an EntityManager using reflection - how did you do that? Why not apply the same to your beans?
B. If you're encountering problems with A, why not develop your own injection code , based on cglib , for example (in order to create Proxy not just for interface, but also for classes).
This way, when an object of the class is created,
you will be able to intercept the default CTOR, and scan for fields annotated with #Ejb.
I would suggest using some sort of configuration file that maps for each bean interface how to instantiate an appropriate class, and run this flow recurisevely (as the injected bean might have a field with #EJB annotation as well).
Pay attention that if you decide to use this method of work, you'll be implementing some sort of "mini dependnecy injection framework" - besides the fact that personally I would be interested in seeing your code ( :) ) I think you should carefully think why you don't want to use an "already made solution.
Note regarding the Arquillian suggestions, that still requires an EJB Container like JBoss, GlassFish, or OpenEJB.
If the problem is just finding and including all the dependencies, try this jar that includes all the required dependencies for EJB Lite:
http://repo1.maven.org/maven2/org/apache/openejb/openejb-lite/4.0.0/openejb-lite-4.0.0.jar
Include that in your test classpath (no other jars needed) then just boot the embedded container:
EJBContainer container = EJBContainer.createEJBContainer();
MyBean bean = (MyBean) container.getContext().lookup("java:global/myModleName/MyBean");
Working example here
Have you look at Arquillian?
You can find all the documentation on the project page: http://www.jboss.org/arquillian.html
I've inherited two fairly non-trivial codebases that uses spring for configuring the applications. Now I need to reconfigure the applications. But lots of the configuration is provided through autowiring so it is almost impossible to find out what the actual configuration is.
The projects are moderately sized, some 20-ish maven modules per project including integration test modules and such. Most modules define a few application contexts for various purposes, that contain one or two local spring config files along with one or two from the core modules it depends on. The result is a myriad of configurations, and that I cannot alter a class or variable name (or setter method) without risking breaking dependencies in some upstream or downstream module, even if no such dependency is visible anywhere in the project.
How do I work effectively with autowired dependencies in spring?
Can anyone, perhaps someone who actually likes autowiring, provide some insight into how you work with them effectively?
(I also inherited a small project that combines xml-files, autowiring and annotation-driven config, making dependency relations completely intractable, but I'll save those annotations for a separate question later)
You can perform re-factoring of auto wired beans using Intellij (I have version 9 Ultimate). Also Intellij has an option of making autowiring dependencies explicit. Link Provided below
http://blogs.jetbrains.com/idea/2009/03/making-spring-autowired-dependencies-explicit/
What IDE are you using? Spring STS (an Eclipse based IDE) has a lot of tools for working with Spring annotations and autowiring as well as good set of refactoring tools.