Can Spring understand #Inject replacing Weld as a JSR-299 implementation? - java

I have noticed from several web pages that apparently Spring 3.0 supports #Inject from JSR-330. As we would really like to use JSR-299 syntax for dependency injection in our libraries for both web apps and stand-alone applications, and have alternatives to Weld, it would be nice if Spring could do this.
Being a novice to Spring, I tried downloading the Spring Framework distribution and put all jars on the Eclipse build path. No Inject annotation so my existing test project using Weld did not compile.
Can this be done with Spring? What do I need to do to get it running?
(I am aware that Guice eventually will support this too. It is only in SVN for now, and if there is an official Spring release which can, that would be better.)
It can be done. The JSR-330 jar must be downloaded seperately, and cglib to parse the manually written #Configuration classes, plus a commons logging implementation.
The largest difference from Weld seems to be that the wiring needs to be manually written instead of magically found (a bit more cumbersome, but may make more robust applications), plus the startup time is much less. I am still new to Spring - is there a way to have #Configuration classes autodiscovered?

From the Spring 3.0.x Reference documentation:
JSR 330's #Inject annotation can be used in place of Spring's #Autowired in the examples below. #Inject does not have a required property unlike Spring's #Autowire annotation which has a required property to indicate if the value being injected is optional. This behavior is enabled automatically if you have the JSR 330 JAR on the classpath.
So you can make your code agnostic of the DI framework by using #Inject, but you still need to include a jar with the javax.inject classes in your project because Spring does not ship them itself. You can find the relevant jar in the downloads section at JSR-330's Google Code site.

The javax.inject package is not included as part of Spring 3, but it does support it if it's present.
If you look at the source for AutowiredAnnotationBeanPostProcessor, you'll see the constructor uses reflection to locate javax.inject.Inject, and logs a message if it finds it. There's no compile-time dependency on it.
You'll need to locate the JSR-330 JARs from some other source (e.g. the JavaEE 6 SDK).

Related

How to build fat jar for EE CDI?

Those days everybody talks about microservices and containerless deployments using fat-jars, and framework like Dropwizard or Springboot support you with that. With all the EE components available as separate implementations it should be possible to assemble your own jar of the required componentes (i.e. Weld, Jersey, Jetty).
When using Java EE based CDI, there is this concept of BDA (Bean Deplyoment Archive), that defines a set of CDI-enabled Beans bundled in jar, together with a beans.xml containing some additional information for the BDA, like interceptors.
How do I combine those BDAs into a single uber-jar without loosing the information of the beans.xml? The maven jar-with-dependencies just copies all files into one, overriding the previous file (or keeping the first one, don't know exactly).
Is the concept of a fat-jar compatible with EE CDI at all? Won't some CDI semantics get lost when being all merged into one BDA, i.e. scope of Alternatives.
Here's a tip from the weld guys http://weld.cdi-spec.org/documentation/#5
Basically,make sure you aggregate your extensions and include a valid beans.xml

Resolve EJB Dependencies without a container

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

How to get annotation like support when my service layer is in another module?

My spring mvc application is broken into modules.
My services are in their own module.
Previously I used to put a #Service annotation on my services, but since they are in a seperate module, that doesn't have spring, how can I wire them up automatically like before in my web application?
If you split application into modules you have split its dependencies too.
For example:
Your ui depends on spring-mvc.
Your services depend on spring-core and hibernate-annotation.
Your services-impl depend on hibernate-core.
And then if your modeles have appropriate dependence. You can use #Service as you used.
Please bear in mind that when you create WAR with your application, all required modules will be placed in WEB-INF/lib along with Spring dependencies (required by MVC module).
So module in which your services are placed may have dependency to spring-context (containing annotations) since the MVC module requires this dependency itself so it will be placed in the final package anyway. If you use maven, it will handle everything under the hood automatically.
However, if you don't want to have dependencies to spring, because, for example, your 'services module' is deployed as a separate, spring-free bundle, you can use JSR330 #Inject, #Resource and #Qualifier Java annotations - these works interchangeable to Spring equivalents. However I don't know Java equivalents of #Service, #Component or #Repository, so in these cases you can rely on XML Spring context configuration in your MVC module.

How to refactor a codebase that uses spring autowiring

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.

<tx:annotation-driven /> leads to java.lang.ClassNotFoundException: org.aopalliance.aop.Advice

Anybody has an idea why adding the annotation-driven declaration leads to the aopalliance classes not found. I have not explicitly defined the weaving so using Spring defaults.
Any help is appreciated
Spring has two modes of creating proxies to support transactions. The default mode is to create JDK proxies, but that only works if you inject interfaces. If you inject classes, CGLib proxies will be used, and they are created using AspectJ (and hence the aopalliance.jar and the spring-aspects.jar are needed on the classpath).
My advice: refer to your services and daos by interface:
private MyDaoInterface dao;
public void setDao(MyDaoInterface dao){
}
and Spring will automatically choose the Proxy-based approach.
See:
<tx:annotation-driven>
settings
Proxying mechanisms
I'm unsure what the real question is (if it is about the real cause1, providing the full stacktrace might be helpful) but the fact is that you are currently missing the aopalliance.jar on your classpath (which was previously included in Spring jars as mentioned in this thread or this blog post).
1 With the provided level of details, my guess is that Spring is loading its TransactionInterceptor which is an implementation of o.a.a.Advice and is looking for the dependency, which is missing.

Categories

Resources