Java EE 6 - Why does an interceptor project need to be declared as ejb-jar and not simply a jar? - ejb-3.0

I was able to determine what I needed to do to get my interceptor working; however, I don't understand why I had to do that. All of the projects I am using my interceptor project in are either jar / war and CDI-enabled.
I thought CDI covered both EJB beans, regular POJO beans, properties, and anything resolveable via EL. And ... that to register an interceptor for CDI beans, I could simply declare it in beans.xml. None of my projects are EARs.
Now that I have it working by building the project as an ejb-jar, that is the main thing, but am I wrong in thinking it should work in beans.xml alone and building the project as just a regular jar?
Please point me to any documentation that specifies this clearly, everything on oracle's site indicates beans.xml should suffice.
Walter

Related

How do you use #Inject with an ejb-jar with (one or more) WAR files?

Working with GlassFish, trying to be tidy, I would like to put all of my business logic into a single EJB JAR. I then have 2 WAR files.
app-frontend-war
app-backend-war
app-logic-ejb
Each of the WAR files need to use the EJBs that are within the app-logic-ejb JAR. This EJB JAR holds the main persistence unit. But I am finding that #Inject of any app-logic-ejb EJB's from any Java within the WAR files are not working.
Also, I am trying to avoid using an EAR.
With the help of the Java EE 7 tutorial I have finally worked it out.
Even though the beans in app-logic-ejb are on the same GlassFish they need to be annotated as remote beans. The WAR files then use #EJB injection (instead of #Inject) into the correct interface within the WAR file.
#EJB
TestBeanInterface t;
To share the interface between the EJB JAR and the War files a Java Library is needed.
So to make it work it turns out I need:
app-library
app-logic-ejb
app-frontend-war
app-backend-war

Difference between running EJB from WAR vs. separate EJB container

Are there any differences in capabilities of the EJB when defining / running it from a WAR vs. an EJB container? What are the benefits vs. drawbacks of deciding on one approach vs. other.
What capabilities do we lose when accessing it from a WAR?
In our case, the developers want to use the EJB for creating / accessing REST webservice.
One of our architects has mentioned below. And for this reason he wants to have a separate EJB that would be added ( the jar ) to EAR but also to WAR for using it as REST endpoint. i would prefer not to have it in multiple places
I’d prefer our approach to put transaction/service based code in EJBs to
leverage Container Managed Transactions, JPA, MDB and all the good stuff EJBs
have to offer.
From the documentation I have read on using EJB as a REST service implementation, it says
Add the EJB class to the WEB-INF/classes directory of your WAR file or to a
JAR that is located in your WEB-INF/lib directory. When a client makes a request
to a JAX-RS annotated enterprise bean, the JAX-RS runtime environment looks up
and uses an EJB instance of the class to invoke the resource method.
So, I want to know, if we put the EJB in the WAR - as in creating the source in the WAR's source so that the class will be added to WEB-INF/classes when the WAR is built, instead of having to put the same ejb jar in two different places based on what it is used for - as a REST webservice endpoint vs. other capabilities, will it satisfy all the requirements or I will have to put the jar in two places?
I am using Websphere 8.5 with EJB 3.1, if that makes a difference in the answer.
There are two primary differences highlighted in section 15.4 of the EJB 3.1 specification:
All EJBs in a WAR share the component namespace (java:comp) with the WAR and all other EJBs in the WAR. Normally, each EJB has its own component namespace. This makes it easier to share reference names and bindings (though this can be done explicitly in EE 6 with java:module or java:app), but it increases the chance of conflict in a large WAR.
EJB classes are loaded by the WAR class loader. In practice, this doesn't matter much, it's just something to be aware of if you encounter class loading problems.
If you want to use an EJB as a REST service, you must package the EJB in the WAR. If you're concerned about "duplicating" EJB logic inside the WAR and for an EJB module, you could declare a base class in the EJB module, and then declare subclasses in the WAR and EJB modules that extend the base class and are annotated #Stateless or #Singleton.
Regarding EJB capabilities there is no difference between packaging an EJB in a WAR or in an EJB module.
There are situations where you have to package EJBs in WARs e.g. if you have a REST endpoint which is at the same time an EJB.
Most often WARs encapsulate frontend functionality. In these situations it is just from a design perspective not advisable to put the EJBs into WARs.

Structuring Spring application with decoupled modules

I am working on a webapp which uses Primefaces as a view, and I inject Spring beans from other projects into JSF Managed beans.
I have an architectural problem:
I've created separate projects(modules) for each component that I use (Business Logic, Persistence, and others) and also create separate projects with their interfaces.
I want my webApp to depend only on the interface of the Business Logic, and to inject the implementation of the BL using Spring Dependency Injection.
I want to achive this recursively: Business logic to depend only on other interfaces, and to inject implementations using spring.
The problem is that having no dependency in the Maven pom file to the actual implementations, when I deploy the application (on a web logic server) the implementation jars are not deployed, and Spring doesn't find the beans to wire.
Is there a way to achieve decoupling without adding dependencies to actual implementations?
Can I include Spring's bean configuration files from other projects if the projects are not added as dependencies?
Did I figured this decoupling all wrong?
I appreciate your ideas.
Well obviously you need the dependencies in your maven pom else nothing will be included. You can add the dependencies with a scope of runtime which includes them in your final war but not during development (scope compile).
For loading the context of modules you might come-up with a naming convention and/or standard location for your files. With that you could do something like this in your web applications beans xml
<import resource="classpath*:/META-INF/spring/*-context.xml" />
This would load all files ending with -context.xml from the /META-INF/spring directory on the classpath (including jar files).

Spring: Injecting services from a different project

In the project our team's working on, we currently have 3 separate Spring projects which utilizes the same services. To avoid redunancy and code copy-pasting, we're planning to create a "common" project wherein all the three projects would be dependent on the common project. In this instance, is it possible to inject these services (perhaps using the #Service annotation) to the Controllers of the Spring projects?
EDIT:
I tried implementing this on my own and what I basically did was I configured the pom.xml to get the Spring Context 3.1.1 dependency (which are also being used by my Spring projects) for my "common" project. With that, I was able to annotate my service with #Service. Afterwards, on my Spring project, I set the component-scan to a level wherein my two projects would meet. On my Spring controller, I #Autowired the service from the "common" project. I ran the Spring project and apparently it worked. Is this the best way to do this?
That's absolutely fine, and standard. Spring (unlike CDI) couldn't care less whether your beans come from the current project or from an imported jar.

How do I get Bundlor to generate Import-Package for OSGi Blueprint dependencies

I'm using Spring and Spring Integration in a service implementation packaged as an OSGi bundle. The service is published by Blueprint, or more specifically Gemini Blueprint [http://www.springframework.org/schema/osgi]
<bean id="myService" class="org.example.mti.MyServiceImplementation"/>
<osgi:service ref="myService" interface="org.example.mti.api.MyService"/>
The context files are in META-INF/spring/applicationContext*.xml
This works fine for some stub services, like memory backed DAOs, which don't rely on libraries for their implementation. The services are registered and can be exercised by another bundle.
For more complicated services, where I'm using Spring Integration, the service implementation clearly needs access to the Spring classes, which are exported by the normal Spring library bundles.
I'm using Bundlor to manage the MANIFEST.MF file. I've tried Spring Bundlor 1.0.0.RELEASE and Eclipse Virgo Bundlor 1.1.0.M3.
My understanding is that Bundlor is meant to be able to scan the Blueprint context files to determine the classes required, but I'm not seeing anything terribly useful added to the Import-Package manifest header.
Import-Package:
org.example.dao,
org.example.domain,
org.example.mti.api,
javax.inject,
org.springframework.integration,
org.springframework.integration.annotation,
org.springframework.integration.support
When trying to run the bundle using Pax Exam, under Felix, I see ClassNotFoundException
java.lang.ClassNotFoundException:
org.springframework.integration.gateway.GatewayProxyFactoryBean
I've tried setting both the Bundle-Blueprint and Spring-Context manifest headers in manifest.mf, and they're copied to MANIFEST.MF, but no new Import-Package values are added.
Is it expected that adding, for example, an <int:gateway .../> into the blueprint context will allow Bundlor to correctly determine the runtime dependencies, such as the GatewayProxyFactoryBean above?
If Bundlor cannot determine the correct Import-Package value then how do you manage these 'internal' package requirements? It's unreasonable, I think, to have to list every possible package within some third party library. Is there some equivalent of the Import-Library I vaguely recall from Spring DM?
References:
http://static.springsource.org/s2-bundlor/1.0.x/user-guide/htmlsingle/user-guide.html
http://blog.springsource.org/2009/09/26/bundlor-adds-support-for-the-blueprint-service/
Answering my own question with a potential solution.
DynamicImport-Package: org.springframework.*
While this is a bit of a hack, it does work

Resources