Java + TomEE. Websockets and Servlets in one project? - java

I'm writing a simple game with JavaEE Websocket technology. Using JSR356, my server-side socket class looks like following:
#ServerEndpoint(
value = "/sock",
decoders = { SocketDecoder.class }
)
public class CardsSocket {
....
#OnMessage
public void onMessage(final SocketInput message, final Session session) {
...
}
...
}
It works perfectly fine, and has no issues. But then I decided to create also some web page for info and stuff. So, without changing anything on previous class, I have created a new one:
#ServerEndpoint(value = "/cards")
public class CardsWebPage extends HttpServlet {
#Override
public void doGet(...) {
...
}
}
And configured web.xml file in WEB-INF directory.
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee
http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
version="3.1"
metadata-complete="true">
<servlet>
<servlet-name>CardsWebPage</servlet-name>
<servlet-class>server.CardsWebPage</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>CardsWebPage</servlet-name>
<url-pattern>/cards</url-pattern>
</servlet-mapping>
</web-app>
And there began troubles. My servelet works - browser shows page on localhost:8080/cards, but client-side socket class can no longer initiate - it falls with Exception:
"javax.websocket.DeploymentException: The HTTP response from the server [HTTP/1.1 404 Not Found] did not permit the HTTP upgrade to WebSocket"
, and nothing seems to fix it. Have I missed some documentation? Is it impossible for a single project to contain both servlets and websocket classes? Because, if I delete web.xml file, then sockets are starting to work like before. Server startup logs containing no warnings or errors in both cases.

Yeah, perhaps sparks is right, and I should simply deploy multiple projects.

Hi why decorating CardsWebPage with #ServerEndpoint? Nothing or if you can to get rid of web.xml #WebServlet should be fine.

Related

Proper ActiveWeb configuration for simple app: server output is empty

I am fighting with ActiveWeb currently. I found, as it seems to me, that it's manual here http://javalite.io/activeweb contains a lot of desinformation.
First it says ActiveWeb is zer-configuration, which is not true. web.xml is still required. Also configuration in java is required. For example, file AppBootstrap.java should be present in appropriate location.
Second, I can't find it yet, how to configure views to work.
I have the following controller
package app.controllers;
import java.util.Date;
import org.javalite.activeweb.AppController;
public class GreetingController extends AppController {
public void index() {
}
public void hello() {
view("date", new Date().toString());
view("name", param("name"));
}
}
and it works as I see in debugger. When I open http://localhost:8080/testapp/greeting/hello, the breakpoint in hello() method is reached.
Unfortunately, the file hello.ftl, located in WEB-INF/views/greeting/hello.ftl is apparently ignored, because the browser output is empty.
Simultaneously, it is 100% empty, i.e. there are no HTTP headers at all. This points to suggestion, that some general config is missing.
Also, I have empty output on EVER query, including
http://localhost:8080/testapp
http://localhost:8080/testapp/greeting
http://localhost:8080/testapp/abracadabra
while some of the requests should return errors or service messages.
Request
http://localhost:8080/
returns 404 which means container is working normally.
My web.xml is follows:
<!DOCTYPE web-app PUBLIC
"-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
"http://java.sun.com/dtd/web-app_2_3.dtd" >
<web-app>
<display-name>Archetype Created Web Application</display-name>
<filter>
<filter-name>dispatcher</filter-name>
<filter-class>org.javalite.activeweb.RequestDispatcher</filter-class>
<init-param>
<param-name>exclusions</param-name>
<param-value>css,images,js</param-value>
</init-param>
<init-param>
<param-name>root_controller</param-name>
<param-value>home</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>dispatcher</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
</web-app>
UPDATE
When I removed root_controller parameter from web.xml, the server started to answer with directory listing on
http://localhost:8080/testapp
Other answers are still completely empty
UPDATE 2
Apparently WEB-INF/views/layouts/default_layout.ftl should be present. Otherwise the results will be empty and no error will be reported.
something is definitely mis-configured in your app. Can you post sources somewhere on Github?
You can also clone this app: https://github.com/javalite/activeweb-bootstrap

Shiro 1.2 not working with Guice (and Vaadin)

First time user, please be kind!
I have a bit of a problem configuring Shiro to filter Vaadin-generated pages using Guice.
I have looked online on various websites including the Apache Shiro's guides and etc. Problem is that most websites tend to do it the 'old' fashion way, i.e. using Shiro 1.1 (which doesn't have native Guice support).
So here is the problem. My pages don't get filtered through Shiro. I have tried a zillion different things including using AOP for method authentication, setting filters up manually in the web.xml. Even setting up a shiro.ini file (which I do NOT want to do under any circumstances).
So here is the list of things I am using:
- Shiro 1.2.0-SNAPSHOT
- Guice 3.0
- Vaadin 6.7.4
Here is my web.xml:
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
id="WebApp_ID" version="2.5">
<display-name>App</display-name>
<context-param>
<description>Vaadin production mode</description>
<param-name>productionMode</param-name>
<param-value>false</param-value>
</context-param>
<filter>
<filter-name>guiceFilter</filter-name>
<filter-class>com.google.inject.servlet.GuiceFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>guiceFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<listener>
<listener-class>com.app.GuiceServletInjector</listener-class>
</listener>
</web-app>
Here is the Servlet Injector:
public class GuiceServletInjector extends GuiceServletContextListener {
private ServletContext servletContext;
#Override
public void contextInitialized(ServletContextEvent servletContextEvent) {
servletContext = servletContextEvent.getServletContext();
super.contextInitialized(servletContextEvent);
}
#Override
protected Injector getInjector() {
return Guice.createInjector(new GuiceServletModule(), new ShiroConfigurationModule(servletContext));
}
Which then creates a ServletModule, which passes the request to the Vaadin app:
protected void configureServlets() {
bind(Application.class).to(VaadinMainWindow.class).in(ServletScopes.SESSION);
bind(BasicHttpAuthenticationFilter.class).in(Singleton.class);
filter("/*").through(BasicHttpAuthenticationFilter.class);
serve("/*", "*").with(VaadinApp.class);
}
Also during the injector stage, please notice that I create a ShiroConfigurationModule, which takes care of the realms and etc:
public class ShiroConfigurationModule extends ShiroWebModule {
#Inject
public ShiroConfigurationModule(ServletContext servletContext) {
super(servletContext);
}
#Override
protected void configureShiroWeb() {
bindRealm().to(ShiroBaseRealm.class).in(Singleton.class);
bind(Realm.class).to(ShiroBaseRealm.class).in(Singleton.class);
processMethodInterceptors();
}
private void processMethodInterceptors() {
MethodInterceptor interceptor = new AopAllianceAnnotationsAuthorizingMethodInterceptor();
bindInterceptor(any(), annotatedWith(RequiresRoles.class), interceptor);
bindInterceptor(any(), annotatedWith(RequiresPermissions.class), interceptor);
bindInterceptor(any(), annotatedWith(RequiresAuthentication.class), interceptor);
bindInterceptor(any(), annotatedWith(RequiresUser.class), interceptor);
bindInterceptor(any(), annotatedWith(RequiresGuest.class), interceptor);
}
}
The realm class returns 'true' for the supports(), but returns 'null' for everything, simulating that the user doesn't exists.
The chances of doing something wrong, or missing a step is very high. Can someone please care to explain what I'm missing so I can at least get a basic HTTP auth up?
Thanks a lot!
Mo.
Naturally the blog link has expired, and the site that is now redirected to contains no trace of that blog article whatsoever.
A copy of the article can be found here.
http://web.archive.org/web/20120413052117/http://www.mofirouz.com/wordpress/2012/01/guice-shiro-1-2-and-vaadingwt/
The crux of the answer: if you are using guice then you MUST include
filter("/*").through(GuiceShiroFilter.class)
in your ServletModule, or else NONE of the related shiro filters will ever get hit.
Right so after a lot of testing and messing about with Shiro (as well as finally using the 1.2-release), I got mine to work.
I've written a detailed answer on my site (primarily because it is easier to write!). Have a look:
http://www.mofirouz.com/wordpress/2012/01/guice-shiro-1-2-and-vaadingwt/
Good luck whoever out there!

Message level Jax-WS service

I'm trying to create a WebService stub. I like to react to all of the request in one single place. I have a sample value generator, which handles the type of the request and creates a sample response, so I don't need the code-generation things with a lots of classes. Only a really simple one.
I have found http://jax-ws.java.net/nonav/2.2.1/docs/provider.html WebServiceProvider which is exactly for getting raw SOAP messages, and create a response in a single place.
The main problem is I'm new to this magical EE world :) and I simply can not start WebServiceProvider sample anyway.
I have Spring, SpringSource ToolSuit, Axis installed/configured, all of the other things are working.
Thank you all for your help, and please excuse me if the question is too simple for you. Maybe I just did not find/read something.
M.
Finally I have found the solution (thanks for the help from my workmates).
If you are using JAX-WS, there is a simple solution.
You need a sun-jaxws.xml in your WEB-INF folder containing the following:
<?xml version="1.0" encoding="UTF-8"?>
<endpoints xmlns="http://java.sun.com/xml/ns/jax-ws/ri/runtime" version="2.0">
<endpoint
name="RawWS"
implementation="com.stg.pack.MyServiceProvider"
url-pattern="/HotelServices200631"/>
</endpoints>
And you need a com.stg.pack.MyServiceProvider class which looks like:
package com.stg.pack;
#ServiceMode(value = Service.Mode.MESSAGE)
#WebServiceProvider(portName = "ThePortNameOfWebService",
serviceName = "TheNameOfWebService",
targetNamespace = "http://www.example.com/target/namespace/uri")
public class MyServiceProvider implements Provider<SOAPMessage> {
#Override
public SOAPMessage invoke(SOAPMessage request) {
SOAPMessage result = null;
// create response SOAPMessage
return result;
}
}
And before I forget, you need to define some things in web.xml:
<listener>
<listener-class>
com.sun.xml.ws.transport.http.servlet.WSServletContextListener
</listener-class>
</listener>
<servlet>
<servlet-name>RawWS</servlet-name>
<servlet-class>
com.sun.xml.ws.transport.http.servlet.WSServlet
</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>RawWS</servlet-name>
<url-pattern>/TheNameOfWebService</url-pattern>
</servlet-mapping>
If you use it like this, all of the request are handled by the invoke method.
you basically must deploy your provider to some sort of Container. developing in J/EE basically mandates that you compile some sort of EAR or WAR or JAR and tell an app server to deploy it (be that app server a JBOSS, glassfish, Weblogic, Websphere, Tomcat, etc).
Have you tried doing this?
it also may be possible to test your provider using the javax.xml.ws.Endpoint class, although I have to admit I've never chosen to per-sue this in favor of deploying to an app server.

GWT + GAE Servlet URL and Servlet Mapping

http://127.0.0.1:8888/socialnetwork/contactsService
That's the current URL for one of my servlets. My question is, how do I change it?
In my web.xml file, altering
<servlet-mapping>
<servlet-name>contactsServiceServlet</servlet-name>
<url-pattern>/socialnetwork/contactsService</url-pattern>
</servlet-mapping>
to
<servlet-mapping>
<servlet-name>contactsServiceServlet</servlet-name>
<url-pattern>/a/contactsService</url-pattern>
</servlet-mapping>
Makes absolutely NO difference to the URL it requests when I make an RPC-call to the servlet.
Once you have done the above you need to change where you invoke (Which is described in the Annotation below) as in...
// The RemoteServiceRelativePath annotation automatically calls setServiceEntryPoint()
#RemoteServiceRelativePath("email")
public interface MyEmailService extends RemoteService {
void emptyMyInbox(String username, String password);
}
See http://google-web-toolkit.googlecode.com/svn/javadoc/1.6/com/google/gwt/user/client/rpc/RemoteServiceRelativePath.html

jax-ws on glassfish3 init method

I've created simple jax-ws (anotated Java 6 class to web service) service and deploied it on glassfish v3. The web.xml
<?xml version="1.0" encoding="ISO-8859-1"?>
<web-app>
<servlet>
<servlet-name>MyServiceName</servlet-name>
<description>Blablabla</description>
<servlet-class>com.foo-bar.somepackage.TheService</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>MyServiceName</servlet-name>
<url-pattern>/MyServiceName</url-pattern>
</servlet-mapping>
<session-config>
<session-timeout>30</session-timeout>
</session-config>
</web-app>
There is no sun-jaxws.xml in the war.
The service works fine but I have 2 issues:
I'm using apache common configuration package to read my configuration, so i have init function that calls configuration stuff.
1. How can I configure init method for jaxws service (like i can do for the servlets for example)
2. the load on startup parameter is not affecting the service, I see that for every request init function called again (and c-tor). How can I set scope for my service?
Thanks a lot,
How can I configure init method for jaxws service (like i can do for the servlets for example)
JAX-WS endpoints, both web and EJB, can have optional life-cycle methods that are automatically called if present. Any method can be used as a life-cycle method with the correct annotation:
#PostConstruct - Called by the container before the implementing class begins responding to web service clients.
#PreDestroy - Called by the container before the endpoint is removed from operation
So annotating your init() method with #PostConstruct should do the trick.
the load on startup parameter is not affecting the service, I see that for every request init function called again
Try to use the suggested annotation first. And if you are still facing unexpected behavior, post your code.
Thanks for the quick answer, Pascal.
BTW, I warmly suggest to use a "valid" servlet 2.5 or servlet 3.0 web.xml (using a version attribute in the web-app element and the xsd declaration).
I'm using 2.5 version, I just didn't paste this part in my post
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:j2ee="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="2.5"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
<description>WebTier for the Login Manager Service</description>
<display-name>LoginManagerWAR</display-name>
<servlet>
<description>Endpoint for Login Manager Web Service</description>
<display-name>LoginManagerControllerService</display-name>
<servlet-name>LoginManagerController</servlet-name>
<servlet-class>loginmanager.controller.LoginManagerController</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>LoginManagerController</servlet-name>
<url-pattern>/LoginManagerControllerService</url-pattern>
</servlet-mapping>
<session-config>
<session-timeout>54</session-timeout>
</session-config>
The PostConstruct works fine , thank you, but load-on-startup still didn't happen.
#WebService(
name="LoginManagerController",
serviceName="LoginManagerControllerService"
)
public class LoginManagerController {
private ILoginManager manager;
#Resource
private WebServiceContext wsContext;
#PostConstruct
private void init(){
.....
}
More over, now every client request makes 2 init() calls of the webservice:
like I can see in chainsaw, first called init() of the service, then it called again and then the actually client's function (I print the hash code of the webservice class instance and it the same instance for both calls!!!):
> Message Inside init() method ... controller=31641446
> Message login manager = 11229828
> .....init of elements....blablabla.....
> Message Exiting init() method
> Message Inside init() method ... controller=31641446
> Message login manager = 32361523
The controller is the service and the manager (wich hash code has been changed from first call to the second) created inside the init () of the controller.
I failed to understand what is wrong ....
UPDATE
It seems like a to glassfish v3 related issue (maybe my env setup or glassfish configuration). I tried this war on Sailfin and Glassfish V2 and its perfectly working ....

Categories