I was reading this enter link description here. Specifically, this section is confusing to me.
Web Service Clients
A web service client can access a Java EE application in two ways. First, the client can access a web service created with JAX-WS. (For more information on JAX-WS, see Chapter 19, Building Web Services with JAX-WS.) Second, a web service client can invoke the business methods of a stateless session bean. Message beans cannot be accessed by web service clients.
Provided that it uses the correct protocols (SOAP, HTTP, WSDL), any web service client can access a stateless session bean, whether or not the client is written in the Java programming language. The client doesn’t even “know” what technology implements the service: stateless session bean, JAX-WS, or some other technology. In addition, enterprise beans and web components can be clients of web services. This flexibility enables you to integrate Java EE applications with web services.
A web service client accesses a stateless session bean through the bean’s web service endpoint implementation class. By default, all public methods in the bean class are accessible to web service clients. The #WebMethod annotation may be used to customize the behavior of web service methods. If the #WebMethod annotation is used to decorate the bean class’s methods, only those methods decorated with #WebMethod are exposed to web service clients.
This is what I am getting from the above article context: Highlighted the text with italics. Points bellow are in order of the highlighted sentences in the text above.
"First, the client can access ..." Means: Any clients that access the Web Services created with JAX-WS. (Of course, any web service created with any tools/technologies can be accessed by any client.).
"Second, a web service..." Means: JAX-WS Web Service can access stateless Session beans.
"any web service client can access" How? Can a .NET Web Service client access a Stateless Session Bean? Or I am understanding this incorrectly?
"A web service client accesses a stateless session bean ..." I am not getting this. Does it mean A Web Service Client accessing the another web service created using Stateless Session Bean?
In order to your points:
The implementation class is not a EJB.
#WebService public class MyService {
#EJB MyBean ejb;
#WebMethod
public void doSomething() { ... }
}
The implementation class is also a EJB.
#Stateless #WebService public class MyServiceBean {
#WebMethod
public void doSomething() { ... }
}
.NET client can access to EJB by:
#Stateless #WebService public class MyServiceBean {
#WebMethod
public void doSomething() { ... }
}
Explanation of 2. The endpoint implementation class is, e.g., MyServiceBean.
Related
I have injected my simple pojo ejb into web service interface and trying to intercept the method simple pojo by using the EJB interceptor but issue is that instance of injected pojo will hold the value that is setted in earlier request of web service
How to solve this issue.
Thanks
Our application consists of web pages that interact with backing beans and Stateless EJB services, but there is also a remote client that interacts with the Stateless EJB services.
Many of the services query the DB and then filter the result set based on the current user/caller (for example, users have permission to view only some record types); that is, they use programmatic rather than declarative security.
On the web side, my intuition would be to store the currently logged-in user in a SessionBean, but I want the Stateless EJB services to filter the result set based on the currently logged-in user so that the filtering also applies during remote client calls. I can inject a SessionBean into a Stateless EJB service, but I think SessionBeans use HTTP sessions, and as there is no HTTP session during a remote client call, I don't see how that could work.
I sense that my approach is wrong, and that I should be retrieving the "Principal" from the container; however, due to our application's development lifecycle, container-managed security is not set-up yet, but I am still tasked to implement the business logic responsible for filtering records now rather than later.
My closely-related questions:
Can a SessionScoped bean be injected into a Stateless EJB knowing that the Statelesss EJB will be invoked by remote clients? What is the value of the SessionScoped bean in that case?
Instead of a SessionScoped bean, should my backing beans and Stateless EJB services be retrieving the Principal from the container?
If yes, how can I substitute a mock Principal to work on the business logic until container-managed security is set-up?
p.s. I am new to Java EE.
Technology:
Java EE 6
GlassFish 3.1.2.2
"Backing bean" e.g. javax.enterprise.context.SessionScoped
"Stateless EJB services", e.g. javax.ejb.Stateless
"remote client"; i.e. some non-web clients invoking the Stateless beans directly (through EJB/RMI)
Update:
More detail on the "remote client". I'm not sure how to word this because I'm new to Java EE, but this "remote client" will not be over HTTP. Another application, let's call it application X, will receive XML messages from clients. I think they authenticate the client using certificates. Application X will transform the XML into POJOs and call my Stateless EJB services directly.
In this case, I think I'm right to say that I should not inject a SessionBean into a Stateless EJB service because there will be no HTTP session when the EJB service is called by Application X. Is my understanding correct?
Thank you for your patience. I am aware of my ignorance in these matters.
You are not fully clear with your questions. Your question let me assume a lot. So you should break your questions down and provide more details to your issue.
First of all you should mention which Java EE version you are using. Anyway here my details with some assumptions to your context.
Assuming you are talking about following
Backing beans: http://docs.oracle.com/javaee/5/tutorial/doc/bnaqm.html
"Stateless beans" == Stateless session beans : http://docs.oracle.com/javaee/6/tutorial/doc/gipjg.html#gipin
SessionScoped beans : http://docs.oracle.com/javaee/6/tutorial/doc/gjbbk.html
"remote client interaction": http://docs.oracle.com/javaee/6/tutorial/doc/gipjf.html#girfl
In the case of the major question, you should keep in mind to separate the Http session from your Stateful session bean: Stateful Session Bean and HTTP Session
So if you try to couple Http Session with a Stateful session bean you have to provide the http session details into a area where both http session and stateful session bean can access the data and also hold a reference to it.
This assumes also, that your remote EJB service will not create a http session first. So you will not have a valid reference to a HTTP session via remote EJBs.
If you are using a HTTP based "remote client interaction", why are you not creating a http session on the first request?
HttpServletRequest.getSession(true)
will ensure what you will always get a valid session
If you are using some other HTTP bases frameworks like jax-rs there are also options to get a http session there.
Update 1
Can a SessionScoped bean be injected into a Stateless EJB knowing that
the Statelesss EJB will be invoked by remote clients? What is the
value of the SessionScoped bean in that case?
You can use the backing beans as POJOs in your EJBs, but not as http session scoped beans. If you need them from remote EJB you have to initialize them first, before using. Means, the have no value on remote EJB calls.
Instead of a SessionScoped bean, should my backing beans and Stateless
EJB services be retrieving the Principal from the container?
Also here the question is not fully clear.
You can configure your container (glassfish) to use have manual user, roles and realms. So this is your local mock for the Security and you can retrieve the Principal from the container.
http://docs.oracle.com/javaee/6/tutorial/doc/bnbxj.html#bnbxs
Independently: I would recommend you to read the Oracle tutorial about Java EE. It is pretty good. Taking some dollars I would recommend Java EE 7 Essentials
Can I have the same service having simultaneously both REST and SOAP interfaces?
I currently have a REST service implemented in Java using EJB and Jersey:
import javax.ejb.EJB;
import javax.ejb.Stateless;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
#Stateless
#Path("test")
public class TestExternalService {
#EJB
private com.test.ejb.db.TestService testService;
#GET
#Path("/status")
#Produces("text/*")
public String status() {
return "ok";
}
}
How can I make changes in my class to also implement a SOAP interface?
Basically, Jersey is JAX-RS implementation, so you cannot have SOAP web-services here. You could take Apache CXF, which is implementation for both JAX-RS and JAX-WS and you would be able to combine your web-services in both architectural styles.
Here is a solution to expose an implementation as both rest and soap web service. Similar to what zack suggested in the comment.
You may have to do some refactoring if you already have the service supporting jax-rs as you pasted above.
The solution is to have two sets of interfaces and implementation. One supporting jax-rs and one jax-ws. You can still have your processing done in the ejb.
Example,
Do not annotate your ejb (say EService) with jax-rs.
Have an interface X and Ximpl class to support restful calls. This will support jax-rs, so basically be annotated with jax-rs. Ofcourse, this can still use jersey. Ximpl will reference the EJB EService and delegate the processing to it.
Have an interface Y and YImpl to support soap based calls. This will support jax-ws, so will be annotated with jax-ws. Yimpl will reference the EJB EService and delegate the processing to it.
If you have a web deployment descriptor, in your web deployment descriptor define different servlets and mapping for rest and soap.
I am learning EJB and I am trying to execute the Helloworld example given in EJB In Action book.
My app server is JBoss, I created the Jar file for the bean class and interface in the right directory( I can see the EJB in JMX console).
Now I created a simple client using EJB annotations, but I am getting a NullPointerException.
Here is my client code.
Client code:
package com.client;
import javax.ejb.EJB;
import com.EJB.*;
public class HelloWorldClient {
#EJB
private static HelloWorldInterface HelloBean;
public static void main(String[] args)
{
HelloBean.SayHelloWorldInEJB();
}
}
Bean class
package com.EJB;
import javax.ejb.Stateless;
#Stateless
public class HelloWorldBean implements HelloWorldInterface {
public void SayHelloWorldInEJB() {
// TODO Auto-generated method stub
System.out.println("Hello world from the world of EJB");
}
}
Interface
package com.EJB;
import javax.ejb.Local;;
#Local
public interface HelloWorldInterface {
public void SayHelloWorldInEJB();
}
Note: I tried using specifying the interface as Remote, it still didn't work.
Steps that I did so far to get to this point.
1) Created the file EJB files
2) Made the build.xml and deployed the EJB.
Am I missing any configuration files ???
Now I created a simple client using EJB annotations, but I am getting a NullPointerException.
Your client code looks like an Application Client and such client is supposed to be deployed on the app server and then executed in an Application Client Container (ACC) so that injection can occur. Starting the ACC requires an application server specific command.
The following wiki explains the usage of the ACC in JBoss (how to package, deploy and launch an ACC): How to use an application client in JBoss-5.
If you don't want to use an Application Client Container and instead just run the application client class through a java command, injection won't be possible and you'll have to perform a JNDI lookup.
And in both cases, you'll have to provide and use a remote business interface for your bean.
Resources
How to use an application client in JBoss-5
Creating and Running an Application Client on the GlassFish Server
Related questions
application-client
You would have to make two changes:
Replace the #EJB dependency injection with JNDI lookup. Dependency Injection is not supported for POJOs in EJB 3 (Don't know about EJB 3.1 though )
Then, the interface has to be a remote interface. The reason is that, the client here is a standalone java program - It would be running in JVM different from the web-app JVM.
Both dependency injection through #EJB and having the interface as #Local should work if the client was a servlet in the same server.
I have an EAR with modules:
foo-api.jar
foo-impl.jar
interceptor.jar
In foo-api there is:
#Local
FooService // (interface of a local stateless session bean)
In foo-impl there is:
#Stateless
FooServiceImpl implements FooService //(implementation of the foo service)
In interceptor.jar I want
public class BazInterceptor {
#EJB
private FooService foo;
#AroundInvoke
public Object intercept( final InvocationContext i) throws Exception {
// do someting with foo service
return i.proceed();
}
The question is:
Will a Java EE 5 compliant application server (e.g. JBoss 5) inject into the interceptor?
If no, what is good strategy for accessing the session bean?
To consider:
Deployment ordering / race conditions
Yes, injection should occur in an interceptor, as mentioned for example in An Introduction to the Java EE 5 Platform article (bold is mine):
Easier Access to Resources Through Dependency Injection
Dependency injection is a pattern in
which an object's dependencies are
supplied automatically by an entity
external to that object. The object is
not required to request these
resources explicitly, for example, by
looking them up in a naming service.
In the Java EE 5 platform, dependency
injection can be applied to all
resources that a component needs,
effectively hiding the creation and
lookup of resources from application
code. Dependency injection can be
applied throughout Java EE 5
technology -- in EJB software
containers, web containers, and
clients.
To request injection of a resource, a
component uses the #Resource
annotation or, in the case of some
specialized resources, the #EJB and
#WebServiceRef annotations.
Following are some of the many
resources that can be injected:
SessionContext object
DataSources object
UserTransaction
EntityManager interface
TimerService interface
Other enterprise beans
Web services
Message queues and topics
Connection factories for resource adapters
Environment entries (for example, strings, integers, and so on)
Resource injection can be requested by
any component class, that is, any
class whose life cycle is managed by
the container. In the EJB software
container, components that support
injection include the following:
EJB technology components
Interceptors
Message handlers for Java API for XML Web Services (JAX-WS) and Java API
for XML-based RPC (JAX-RPC)
In web containers, components that
support injection are the following:
Servlets, servlet filters, event listeners
Tag handlers, tag library event listeners
Managed beans
In the client container, the main
class and the login callback handler
components support injection.
See also the EJB Interceptors section of the JBoss EJB 3.0 Tutorial:
Just like a bean class, an interceptor
can be the target of Dependency
injection. The format for how this
works is the same, and the injection
works off the same ENC as the bean to
which the interceptor is bound.
...
Remember that interceptors follow the
same lifecycle as the bean they are
bound to. The interceptors are created
at the same time as the bean instance
is created, and dependency injection
occurs before the first business
method is called.
Resources
An Introduction to the Java EE 5 Platform
EJB 3.0 Tutorial
EJB Interceptors (see the Injection section)
My experience has indicated the injection can only occur in managed classes: EJB (Entity, Session or Message) and Servlets.