I have been given a Java application to maintain and a little confused as to what type of java application it is. The application is quite complex with numerous packages, uses Hibernate and runs on Tomcat.
There is NO servlet class and so no doGet or doPost methods etc and no front end in JSP for example, however it uses javax.servlet.http.HttpSession and in the tomcat\lib folder there is an "servlet-api.jar". Upon looking at the Java classes there is one in particular with web service and web method annotations so is the class with web service end points but there is no "MAIN" method in this class. Also there is a WSDL file in the WebContent\WEB-INF\wsdl location
I have determined that it uses the javax.servlet.http.HttpSession for controlling the session and uses session parameters and some of the imports for the Java class that has the web service annotations are;
import javax.annotation.Resource;
import javax.jws.HandlerChain;
import javax.jws.WebMethod;
import javax.jws.WebParam;
import javax.jws.WebService;
import javax.servlet.http.HttpSession;
import javax.xml.ws.WebServiceContext;
import javax.xml.ws.handler.MessageContext;
I have done work with servlets and java web services before but I suppose the question I am asking is - is this a web service application using a servlet api for the HTTP session aspects or is this a Java servlet using JWS components to provide web service end points?
Here is examples of two of the annotations in the relevant Java class;
#WebService(targetNamespace = *manager won't allow me to show anymore of this*
#WebMethod
public String findPrice( ......
Related
Although I have used EJB earlier, I want to re-assure myself that I understand how it really works.
So, I created a Simple Session Bean EJB (3.1), and packaged it as .ear (which has client jar as well). The below is the snippet:
Session Bean Implementation:
package com.example;
import javax.ejb.Stateless;
#Stateless
public class FirstSessionEJB implements FirstSessionEJBRemote {
public FirstSessionEJB() {
}
#Override
public String print() {
return "Hello";
}
}
Remote interface:
package com.example;
import javax.ejb.Remote;
#Remote
public interface FirstSessionEJBRemote {
public String print();
}
I deployed this EJB as .ear and it was successfully deployed in Wildfly 10.x.
Now, I want to access this using a standalone Java client, running in a separate JVM.
Here is the client code (It might not be completed as I am not clear on how to invoke mainly due to JNDI).
package com.example.main;
import java.util.Hashtable;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import com.example.FirstSessionEJBRemote;
public class Main {
public static void main(String[] args) throws NamingException {
String GLOBAL_JNDI_NAME="java:global/FirstEJBProjEAR/FirstEJBProj/FirstSessionEJB!com.example.FirstSessionEJBRemote";
Hashtable<String,String> jndiProperties = new Hashtable<>();
jndiProperties.put(Context.URL_PKG_PREFIXES, "org.jboss.ejb.client.naming");
InitialContext ic = new InitialContext(jndiProperties);
FirstSessionEJBRemote ejbRemote = null;
ejbRemote = (FirstSessionEJBRemote)ic.lookup(GLOBAL_JNDI_NAME);
ejbRemote.print();
}
}
I referred to this link on how to do the JNDI lookup (and what all parameters to use in, however it is not working.)
In the link it is mentioned that it has Wildfly specific jar which works without JNDI lookup.
Can anyone help me understand:
1) What all properties I need to set up for JNDI look up?
2) Is there any specific jar that needs to be present in client side application?
I don't want to use any specific Wildfly jar, that is, I want to go with traditional JNDI lookup, so can anyone please guide me on this?
It is very frustrating to struggle just to write a simple "Hello world" kind of EJB. I referred to some books are well, but all what they have provided is just the "lookup" code without actually telling what all properties needs to be included for JNDI and any jar to be included.
As the article you link to states albeit a bit hidden in that mountain of text, you do need the jboss-client.jar that you will find in the Wildfly server installation (bin/client/jboss-client.jar); it needs to be on the client's runtime classpath. It contains to begin with that org.jboss.ejb.client.naming package referenced in your code.
The jar contains the extra bit of magic for a client to be able to setup and maintain EJB remote invocations with the Wildfly server, just using JNDI isn't going to cut it. And there is no one jar to rule them all, each container (Wildfly, Glassfish, Weblogic, etc.) has its own implementation for a client library.
Do note that invoking EJBs from a client application is very old school (read: you don't want to do that). A more realistic and modern day view of EJB technology is to use it within an enterprise container itself, such as from a web application / war - say as part of a RESTful service. You likely don't even need the extra layer of the EAR file then, you can just package everything neatly into the one war application.
And in that scenario if you do have a client application, that client can talk to the RESTful service - a much simpler and cross-server, cross-platform communications interface.
I'm developing multiple web applications in Eclipse Mars 2 using java 1.7. I build the files using Maven and test them using a jboss (WildFly) plugin. Each of them uses a web.xml and share 90% of their logic. They all use spring, they all use the same session config, the same filters etc. The difference is the authorization checks and security roles.
Recently I had to do some updates, and it was burden to update all web.xml separately. I'm looking for a solution to define a "web.xml" parent or master file which houses all the common logic, and then inject the small specific parts. What options do I have?
I would move as much as you can out of web.xml and into annotations on the classes. For example, on a filter, you can do something like:
import javax.servlet.Filter;
import javax.servlet.annotation.WebFilter;
import javax.servlet.annotation.WebInitParam;
#WebFilter(filterName = "TimeOfDayFilter",
urlPatterns = {"/*"},
initParams = {
#WebInitParam(name = "mood", value = "awake")})
public class TimeOfDayFilter implements Filter {
(taken from here)
In this way, you've moved much of the traditional configuration that is done in web.xml into the Java class. The same thing can be done with servlets.
Note that this isn't always the right answer. In filters, for example, you can only order them (that is, have a chain of filters) if you're using web.xml. But the more you can move out of web.xml the better.
I was trying to execute a simple Web Service example from a book:
package com.alsb.hello;
import javax.jws.WebMethod;
import javax.jws.WebService;
import javax.jws.soap.SOAPBinding;
import weblogic.jws.WLHttpTransport;
import weblogic.jws.WSDL;
#WebService
#WSDL(exposed=true)
#WLHttpTransport(portName="HelloWorldSoapPort", serviceUri = "HelloWorldService", contextPath = "business/hello")
#SOAPBinding(parameterStyle=SOAPBinding.ParameterStyle.WRAPPED)
public class HelloWorld {
#WebMethod
public String hello(String arg) {
return arg + "z";
}
}
But when i start the server (Weblogic 10.3.6) it happens the following error:
Errors: The annotation weblogic.jws.WSDL is not allowed on
com.alsb.hello.HelloWorld because it is a JAX-WS type web service.
The same happens with the annotation #WLHttpTransport.
Could someone figure out where's the problem?
"Although this release of WebLogic Server supports both JAX-RPC 1.1 and JAX-WS 2.0 based Web Services, you can use the WebLogic-specific annotations only with JAX-RPC-based Web Services.", check Overview of JWS Annotation Tags from Weblogic. Maybe this could be the reason.
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'm trying to mock an HTTPServletRequest data on my development GAE server. I'm running Eclipse Plugin 1.3.7
I've tried to do this:
package com.FOO.madservice.servlet.mock;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import static org.mockito.Mockito.*;
#SuppressWarnings("serial")
public class BAR2ServletMock extends HttpServlet {
...
protected HttpServletRequest requestFilter(HttpServletRequest req) {
HttpServletRequest servletRequest = spy(req);
doReturn("gzip, deflate").when(servletRequest).getHeader("header-name-goes-here");
doReturn("174.30.216.4").when(servletRequest).getRemoteAddr();
return servletRequest;
}
...
}
Running the following gives exception:
java.lang.NoClassDefFoundError: sun.reflect.ReflectionFactory is a restricted class. Please see the Google App Engine developer's guide for more details.
Any ideas on how to disable class while list checking on GAE development server or perhaps using a different mocking library that works with GAE?
Thanks,
Maxim.
I doubt that you'll be able to get around this on the GAE.
The GAE is compliant with the Java Servlet Standard, so you could probably test out your program by installed a standard Java Servlet Container such as Tomcat.
Also, doesn't object mocking require reflection, by definition of "mocking"? The GAE whitelist is absolutely enforced, and you will not be able to get around it. To deploy on the app engine, there is no way to use the full reflection API (some classes are supported, however).