Can we use #EJB annotation in Apache tomcat [duplicate] - java

This question already has answers here:
How to deploy EJB based application on Tomcat
(4 answers)
Closed 7 years ago.
Can we use #EJB annotation in Apache tomcat?
If we can use #EJB annotation in Apache tomcat then please tell me that what kind of attributes and methods must be there in the service class like the EmployeeService class in the answer of question asked on this link.

No, Tomcat isn't an EJB container. Only Glassfish 3, JBoss AS 6, etc are. For Tomcat you have to install it separately. The linked answer was just a basic kickoff example. You can do it as good without EJB. You only need to create it yourself during bean's initialization, construction or postconstruct. E.g.
private UserService userService = new UserService();
or
private UserService userService = ServiceFactory.getUserService();
etc.
Note that this isn't existing code. It's just code which you have to write yourself. All it contains are just methods which does all the database interaction task. In an EJB capable container you'd use JPA for this. But on a simple servletcontainer like Tomcat you'd need good ol' JDBC for this. You can find extensive kickoff examples of a basic JDBC DAO in this blog.

As of October 2011 Apache does have a Java EE certified version of Tomcat
The certified version is called Apache TomEE and is a plain Tomcat zip file with the right jars added so that it can pass the Java EE 6 Web Profile TCK.
So you can use EJB, JSF, JPA and more in Tomcat just as you can with GlassFish, JBoss, etc. on a version of Tomcat shipped from Apache.

Apache is a servlet container which is only a part of Java EE specification. Once found, #EJB annotations will be skipped and no injections will be made by Tomcat. If you want your servlet to call EJB methods you will need to make JNDI lookups on servlet startup and put remote interface classes in servlet's classpath.

Related

Liferay Portal: OSGI Modularity with JSF and EJB- CDI not injecting/retrieveing with #Resource

I am currently working on the Liferay 7.1.2.ga3 CE with tomcat and was going over the OSGI section of the tutorial in the official documentation.
This one: Docs
I decided to give it a shot with the simplest project possible.
I have created a Liferay Workspace in my IntelliJ idea and added some component as discribed in the turorial.
The problem is that it either does not inject or does inject but does not retrieve the dependecy because in this case in the consumer the _applicationServices variable is always at null.
EDIT: I have asked the same question in the official Liferay forum here : Question in Liferay.org
Here is the code:
The api:
#ProviderType
public interface ApplicationServices {
String getSearchFiltersForRegister(String registerCode);
}
The provider:
#Component(
immediate = true,
property = {
},
service = ApplicationServices.class
)
public class ApplicationServicesImpl implements ApplicationServices {
#Override
public String getSearchFiltersForRegister(String registerCode) {
return "OSGI modularity made service";
}
}
The consumer:
#ManagedBean(name = "registerSearchBean")
#ViewScoped
#Component(
immediate = true,
property = {
"osgi.command.scope=getSearchFiltersForRegister",
"osgi.command.function=getSearchFiltersForRegister"
},
service = Object.class
)
public class RegisterSearchBean {
public String message;
#Reference
private ApplicationServices _applicationServices;
#PostConstruct
public void initBean(){
getSearchFiltersForRegister();
}
public void getSearchFiltersForRegister(){
ApplicationServices applicationServices=_applicationServices;
message=applicationServices.getSearchFiltersForRegister("asd");
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
}
NOTE: I have also tried to separate the consumre module in a different class and use it in this bean without success.
Additional info:
The project is a gradle LiferayWorkaspace.
Api and services modules are generated via the Liferay plugin in the
modules folder.
The JSF module is generated via the maven archetype with gradle
support in the "war" folder.
Dependecies are correctly defined and it is all correctly deployed in
the Liferay Server. At least it appears so.... no errors for missing classes appear on deploy.
What am I doing wrong and why application services is always null?
Answered extensively by Neil Griffin on the liferay forum.:
Hi Georgi,Thanks so much for reaching out. You asked a very important
question that deserves a thorough answer. Since JSF is a technology
based on Java EE, it expects the project to be a Web Application
ARchive (WAR) rather than a Java ARchive (JAR). When the WAR is
deployed to $LIFERAY_HOME/deploy, Liferay will automatically convert
the Java EE WAR to an OSGi Web Application Bundle (WAemoticon.
Although WABs are first-class OSGi citizens, they do not participate
in the build-time discovery of services via classes annotated with
#Component. The more natural fit for WABs is CDI, which accomplishes
deploy-time discovery of services by scanning the classpath.So the
difficulty with the code that you pasted is this: You are combining
OSGi Declarative Services build-time discovery (via #Component) with a
CDI deploy-time discovery (via #ViewScoped). These need to be used in
a mutually exclusive way -- In other words, they cannot be
combined.Here's the encouraging news -- Liferay 7.1, 7.2, and 7.3 ship
with weld-osgi-bundle.jar in $LIFERAY_HOME/modules and fully supports
the CDI requirements of Portlet 3.0 via OSGi CDI Integration. This
means it is possible to develop WARs that use JSR 330 #Inject in order
to inject services from the OSGi Service Registry into CDI beans. It
also makes it possible to publish CDI beans into the OSGi service
registry. I recently gave a talk at Liferay DEVCON 2019 titled Portlet
3.0 MVCBean and PortletMVC4Spring that demonstrates the promise of OSGi CDI integration. If you have time, I recommend that you watch the
presentation because it should help you get a better idea as to how it
all works. But I'm sorry to say the JSF isn't quite able to take
advantage of this yet. We're still working on our implementation of
JSR 378, which makes it possible to deploy a JSF portlet within
Liferay as a Portlet 3.0 "bean portlet" -- that's the part that
enables all the OSGi CDI Integration functionality. We have it working
in the 5.x branch of the liferay-faces-bridge-impl.git repository but
won't be able to cut a production release until JSR 378 is complete.So
unless you want to experiment with the 5.x version of the bridge, then
I recommend that you follow the advice in the my DEVCON 2016
presentation titled Developing WABs With a View to the Future in which
I describe how to use a ServiceTracker in order to acquire services
from the OSGi Service Registry within a WAR portlet like those
required by JSF.Having said that, it would probably be a good idea for
you to develop OSGi services with #Component (Declarative Services) in
a JAR module. The JAR module can be deployed separately from your JSF
portlet WAR module. That way, you should be able to acquire the
service (defined by #Component) from the OSGi Service Registry via the
ServiceTracker in your JSR managed bean. Eventually, once we release
JSR 378, you will be able to use JSR 330 #Inject instead of the
ServiceTracker in order to inject your OSGi service into your JSF
managed bean (managed by CDI via #javax.faces.view.ViewScoped). Just
to clarify, again, in the future, you would want to use the CDI
compatible version of the #ViewScoped annotation and not the one
intended for use with the JSF Managed Bean Facility (MBF) which is
#javax.faces.bean.ViewScoped.Kind Regards,Neil

Can we have a deployment Descriptor in EJB 3.x

I am trying to narrow down the major changes in in EJB 3 and EJB 2, and noted the following changes
EJB 3.X does not required a deployment descriptor; does this mean we can not have a deployment descriptor ?
Also the home and the remote interfaces ? does this mean we can not implement any the aforementioned interfaces in EJB 3.x. Can someone explain what are the main use of Home and the remote interfaces in EJB 2.x
EJB 2.x does not use or implement POJOs , can some one explain the exact use of POJOs in EJB 3.x, with a minor example
I have covered EJB 3, yet I do not have any knowledge in EJB 2.x
Regards
Rashendra
ad 1/ One can certainly have explicit XML-based deployment descriptor with EJB 3.0. However, as compared with 2.x, it is not anymore obligatory to have one. One uses explicit XML deployment descriptor when some of the settings specified on Java class itselfs needs to be augmented.
ad 2/ There is an remote/local bean interface with EJB 3.0, obligatory with remote beans and optional with local beans. There is no home interface in 3.x anymore, which was used to manage the live cycle of entity beans (read:data) and session beans in 2.x. As the entity beans have been replaced by JPA and the life cycle management of session beans has been removed from the client code written by application developer, there is no need for home interface anymore.
ad 3/ Have a look at Java EE tutorial, it covers this well and there are certainly examples.

Creating EJB 3.0 or 3.1

I would be very much thankful to clear me some question about this new EJB3.0 and above version:
1) if suppose I need ejbCreate, ejbActivate and all other events so how can I get it from the new EJB3.0 and above ver.
2) I always have problem to find particular xml file to alocate a JNDI name according to variety of Application Servers so is there any way that I can give JNDI name without xml file and can also be use a portable name that in every Application Server it can be findable of EJB deployed on app server remotely
3)Can any buddy tell me, i have hosting plan of Java/Linux which supports
i) Tomcat - 5.5.xSupport
ii)JDK - 1.6.x Support
iii)JSP/servlet - 2.0 Support
can it be possible that EJB 3.1 be deployed because some where i have got that tomcat is not able to deploy EJB so please give me some advice help...
Thank You...!!!
please Help me...!!!
1) if suppose i need ejbCreate, ejbActivate and all other events so
how can i get it from the new EJB3.0 and above ver.
In EJB 3 and above, the EJB lifecycle is handled through life cycle annotations, such as: #PostConstruct and #PreDestroy.
2) i always have problem to find perticular xml file to alocate a JNDI
name according to variety of Application Servers so is there any way
that i can give JNDI name without xml file and can also be use a
portable name that in every Application Server it can be findable of
EJB deployed on app server remotly
The #Stateless and #Stateful annotations have two attributes that might solve this issue (name and mappedName). Yet
The mapped name is product-dependent and often installation-dependent.
Hope it helps you.
1) ejbCreate, ejbActivate etc. are related to EJB 2.x, if you need similar functionality in EJB 3.x, you should decorate your methods with annotations #PostActivate, #PrePassivate etc. Method signature should follow certain rules, example for #PostActivate:
The method annotated with #PostActivate must follow these
requirements:
The return type of the method must be void.
The method must not throw a checked exception.
The method may be public, protected, package private or private.
The method must not be static.
The method must not be final.
This annotation does not have any attributes.
2) It seems that you're referring to name and mappedName attributes of #Stateless and #Stateful annotations. For more details see official documentation. From my experience mappedName is better, but it's application-server-specific, e.g. on Glassfish it works perfectly. Example:
#Stateless(mappedName="ejb/myBean")
public class MyFirstBean {
..
}
Since no one answered Question 3 ..
3)Can any buddy tell me, i have hosting plan of Java/Linux which supports i) Tomcat - > 5.5.xSupport ii)JDK - 1.6.x Support iii)JSP/servlet - 2.0 Support
No, you are going to need a server that supports Java EE. Read How to deploy EJB based application on Tomcat

Adding rest service to a struts application

I'm trying to add rest services to a struts application using jersey.For this i need to segregate the java code in such a way that it can be commonly accessed by both the struts and rest api.This is done so that the code is shared between both rest and struts,and any change will reflect in both the services.I would like to know , how much of this idea is feasible and weather this is how usually people design rest services .
While our presentation layer isn't Struts based (usually it's either Spring Web MVC or JSF), we use Spring 3.0 + Java EE 6, specifically, EJB 3.0 and JPA 2.0 for such situations.
EJB 3.0 stateless session beans work great—they can have declarative (annotation-based) dependency injection and transaction demarcation, or they can manage their transactions, dependencies and resources themselves using whatever traditional mechanism. They seamless integrate with JPA 2.0 and are easy enough to unit test. The main advantage over pure Spring beans is that they can be deployed independently of the Web application (as an EJB JAR).
On the front-facing Web services, we also use Jersey/JAX-RS. Because Jersey/JAX-RS dependency injection is broken (it doesn't use Weld/CDI like the rest of Java EE), we've had to resort to Spring DI to 'wire' up the front-facing REST resource classes with the 'back-end' EJBs. The good thing is this works well enough to inject the EJBs into our MVC controllers and can also be used with JSF managed beans. Alternatively, you can write your REST-ful resources using Spring alone (either way has its own pros/cons, but in general both do the job well).
I know I glossed over the whole thing but I'd be glad to share more details upon request.
EDIT: Some more details, as per request.
You're first stop for learning Jersey/JAX-RS would have to be the Jersey User Guide. There are also several tutorials/examples you can easily find across the 'Net.
While you should be able to package Jersey/JAX-RS resources into the same WAR as your Struts pages, we went with the simpler alternative of deploying them separately.
Now, when deploying to Glassfish 3.1, we hit this bug, also documented here. The bottom line is that #EJB injection didn't work for us as expected.
So, instead, we fell back on to Spring using the jersey-spring contrib module, following this example.
Anyway, the rest of it is standard Java EE 6 / EJB 3.0. We identify and place all common functionality into a 'service' layer which are largely implemented as #Stateless EJBs.
Persistence is handled through JPA #Entitys accessed through a JPA inject EntityManager. Transactions are declaratively demarcated using #TransactionAttribute.
Here's a quick illustration of a typical EJB + JPA service bean:
#Stateless
public class WidgetServiceBean implements WidgetService {
#PersistenceContext
private EntityManager em;
#Override
public List<Widget> findWidgetByName(String name) {
return em.createNamedQuery("Widget.findByName", Widget.class)
.setParam("name", name).getResultList();
}
#Override
#TransactionAttribute(TransactionAttributeType.REQUIRED)
public void removeWidgetById(int id) {
em.find(Widget.class, id).remove();
}
}
(Obviously not production quality but just shows how 'lean' they can be.)
The service layer and entities are packaged as an EJB JAR which can be deployed separately, and made available to all other modules via global JNDI lookup. Or, they can be deployed within the Struts or JAX-RS WAR and as of Java EE 6 (Glassfish 3.x) they will be found, deployed as part of the module and made available to other components within the same WAR.
Some might argue that it's simpler to just use Spring beans if you're using the Spring container anyway. I would say, probably, but then you also have to use Spring's persistence framework, and Spring's transaction framework. (Spring also provides declarative transactions and persistence.) If you're already heavily invested into Spring then that might be an easier path.
OTOH, EJB 3.0, JPA 2.0 and JTA have also been radically simplified from their predecessors and are part of the Java EE standard so it's an architectural decision with a lot of dimensions.

Annotations (#EJB, #Resource, ...) within a RESTful Service

I'm trying to inject a EJB within my RESTful Service (RESTEasy) via Annotations.
public class MyServelet implements MyServeletInterface {
...
#EJB
MyBean mybean;
...
}
Unfortunately there is no compilation or AS error, the variable "mybean" is just null and I get a NullPointerException when I try to use it.
What I'm doing wrong?
Here are some side-informations about my architecture:
JBoss 4.2.2.GA
Java version: 1.5.0_17
local MDB-Project
remote EJB-Project
WAR Project with the RESTful Service which uses the remote EJB and sends messages to the local MDB-Project
Thanks in advance!
br
Dominik
p.s: everything is working fine when I use normal context lookup.
I had a similar problem (though without #Remote beans). The way it worked for me - sample application is here: https://github.com/kubamarchwicki/rest-app/ (this works: https://github.com/kubamarchwicki/rest-app/blob/master/service-webapp/src/main/webapp/WEB-INF/web.xml#L9)
The crack with context lookup is that the name changes with a change of the ear name. If you fancy things like versions, it makes the whole thing hard to trace or forces you to hardcode ear name somewhere in the code.
Just a few cents to an old discussion ;-)
This is not exactly my forte, so maybe I am way off... but, can you do EJB stuff in a WAR? I was under the impression you needed to do EJB work in an EAR.
JBoss 4.2.2.GA is not a fully compliant Java EE 5 server, it does not support EJB references injection in servlets or application clients, only in the EJB layer. Use JBoss 5 for that (or perform a lookup).
JBoss 4.2.2.GA supports only Servlet 2.4. There is no support of DI on Servlet 2.4. Hence you always get 'null' for myBean variable. As suggested, please migrate to JBoss 5.0 which supports Servlet 2.5 which makes use of Java 5 features like annotations.

Categories