Error Code 500 on Embedded Glassfish 4.1.1 with Arquillian - maven

I am quite new to Java EE and Arquillian. I am getting problems if I want to deploy my simple project into the embedded glassfish 4.1.1 server. I can succesfully pass the deployment, but I can not access the methods that i implemented. I am getting error code 500, while i expect 200.
my deployment:
public class AuthTest
{
#Deployment(testable = false)
public static WebArchive createDeployment()
{
System.out.println("\nin createDeployment");
// File[] libs = Maven.resolver().loadPomFromFile("pom.xml").importRuntimeAndTestDependencies().asFile();
WebArchive archive = ShrinkWrap.create(WebArchive.class, "ArquillianHepInterface.war")
.addClasses(AuthEndpoint.class)
.addPackage(Database.class.getPackage())
.addPackage(DeviceAccessDBEntry.class.getPackage())
.addPackage(WebsiteAccessDBEntry.class.getPackage())
.addPackage(DeviceInfo.class.getPackage())
.addPackage(LoginInfo.class.getPackage())
.addPackage(ResponseBoolean.class.getPackage())
.addAsWebInfResource(EmptyAsset.INSTANCE, "beans.xml")
.addAsWebInfResource(new File("src/main/webapp", "WEB-INF/web.xml"))
.addAsWebInfResource(new File("src/main/webapp", "WEB-INF/glassfish-web.xml"))
.addAsResource("META-INF/persistence.xml")
// .addAsLibraries(libs)
;
System.out.println("\nende createDeployment");
return archive;
}
#ArquillianResource
protected URL contextPath;
#Test
public void registerUUIDTest()
{
DeviceInfo newUser = new DeviceInfo();
newUser.setDate("2014-12-12");
newUser.setUuid("xyz");
Response i = expect().statusCode(200).when().given().
contentType("application/json").body(newUser)
.post(this.contextPath + "AUTHENTICATION/CREATEMOBILELOGIN")
;
}
my AuthEndpoint class:
#Path("/AUTHENTICATION")
public class AuthEndpoint
{
#Inject
private DatabaseInterface database;
#POST
#Produces({ "application/json" })
#Consumes({ "application/json" })
#Path("CREATEMOBILELOGIN")
public LoginInfo createMobileLogin(DeviceInfo info)
{
System.out.println("RICHTIGES FILE");
System.err.println();
LoginInfo response = null;
if (info != null && info.getUuid() != null)
{
String password = this.database.registerDevice(info.getUuid());
if (password != null)
{
response = new LoginInfo();
response.setPw(password);
response.setUuid(info.getUuid());
}
}
return response;
}
}
I am getting:
SEVERE: WebModule[/ArquillianHepInterface]StandardWrapper.Throwable
Why is that happening? I do not understand where my problem is...
I supposed that I have problems while I am using glassfish 4.1.1...? I want simply to call the Methods in the AuthEndpoint class throught the Arquillian TestClass to verify that a single have been created...
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_3_0.xsd"
version="3.0">
<display-name>Arquillian Rest Demo</display-name>
<servlet>
<display-name>JAX-RS REST Servlet</display-name>
<servlet-name>REST-Servlet</servlet-name>
<servlet-class>com.sun.jersey.spi.container.servlet.ServletContainer</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>REST-Servlet</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>
</web-app>
glassfish-web.xml:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE glassfish-web-app PUBLIC "-//GlassFish.org//DTD GlassFish Application Server 3.1 Servlet 3.0//EN" "http://glassfish.org/dtds/glassfish-web-app_3_0-1.dtd">
<glassfish-web-app>
<context-root>/ArquillianHepInterface</context-root>
<class-loader delegate="true" />
</glassfish-web-app>
My beans.xml file is empty.
The methods that AuthEndpoint uses are in another maven project that I have compiled and added in the maven dependencies...
I would appreciate any help...

Related

how can I get the response message from Axis2 in spring integration

I need to integrate my webservice (Axis2) in spring integration: I have spring-axis2-message.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans:beans xmlns="http://www.springframework.org/schema/integration"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:beans="http://www.springframework.org/schema/beans"
xmlns:stream="http://www.springframework.org/schema/integration/stream"
xmlns:ws="http://www.springframework.org/schema/integration/ws"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/integration
http://www.springframework.org/schema/integration/spring-integration.xsd
http://www.springframework.org/schema/integration/stream
http://www.springframework.org/schema/integration/stream/spring-integration-stream.xsd
http://www.springframework.org/schema/integration/ws
http://www.springframework.org/schema/integration/ws/spring-integration-ws.xsd">
<chain input-channel="messageChannelIN" output-channel="messageChannelOUT">
<ws:header-enricher >
<ws:soap-action value="getMessageService"/>
</ws:header-enricher>
<ws:outbound-gateway uri="http://localhost:8080/axis2-webservice/services/wservices?wsdl" reply-channel="messageChannelOUT"/>
</chain>
<!-- The response from the service is logged to the console. -->
<stream:stdout-channel-adapter id="messageChannelOUT" append-newline="true" />
</beans:beans>
And a TestAxis2.java
package org.neos.spring.test;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.integration.support.MessageBuilder;
import org.springframework.integration.support.channel.BeanFactoryChannelResolver;
import org.springframework.messaging.Message;
import org.springframework.messaging.MessageChannel;
import org.springframework.messaging.core.DestinationResolver;
public class TestAxis2 {
public static void main(String[] args) {
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(
"/META-INF/spring/integration/spring-axis2-message.xml");
DestinationResolver<MessageChannel> channelResolver = new BeanFactoryChannelResolver(context);
String requestXml =
"<getMessageService xmlns=\"http://service.ws.axis2.neos.org\">" +
"<name>HUGO</name>"
+ "</getMessageService>";
// Create the Message object
Message<String> message = MessageBuilder.withPayload(requestXml).build();
// Send the Message to the handler's input channel
MessageChannel channel = channelResolver.resolveDestination("messageChannelIN");
channel.send(message);
}
}
The program run very well and I can see in the console the next response:
<?xml version="1.0" encoding="UTF-8"?><ns:getMessageServiceResponse xmlns:ns="http://service.ws.axis2.neos.org"><ns:return>HELLO HUGO!, WELCOME TO WEBSERVICE AXIS1 hola</ns:return></ns:getMessageServiceResponse>
My question is how Can I manipulate/How can get the response in Java program because I need the response. I tried to do a lot of things but unfortunately did not work anything I only can see the response in the console but I need to manipulate the response.
I do not how can I access this configuration or if I need to configurate other things.
access<stream:stdout-channel-adapter id="messageChannelOUT" append-newline="true" />
Can Anyone help me please?
Use a Messaging Gateway.
public interface Gateway
String sendAndReceive(String out);
}
<int:gateway service-interface="foo.Gateway"
default-request-channel="messageChannelIN" />
Remove the output-channel from the chain
The reply will be returned to the caller via the gateway
Gatweway gw = context.getBean(Gateway.class);
...
String reply = gw.sendAndReceive(requestXml);
This has the added bonus of not exposing your application to the messaging infrastructure.
It's working my program right now!!. Thanks for your help Gary Russell!!! your comments were very useful.
The final code was:
xml configuration
........
<chain input-channel="messageChannelIN">
<ws:header-enricher>
<ws:soap-action value="getMessageService"/>
</ws:header-enricher>
<ws:outbound-gateway uri="http://localhost:8080/axis2-webservice/services/wservices?wsdl" />
</chain>
<gateway id="messageChannelOUT" service-interface="org.neos.spring.ws.service.GatewayAxis" default-request-channel="messageChannelIN"/>
Java Code:
public interface GatewayAxis {
#Gateway
String sendAndReceive(String out);}
TestAxis2
public static void main(String[] args) {
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(
"/META-INF/spring/integration/spring-axis2-message.xml");
GatewayAxis gateway = context.getBean(GatewayAxis.class);
String requestXml =
"<getMessageService xmlns=\"http://service.ws.axis2.neos.org\">" +
"<name>HUGO</name>"
+ "</getMessageService>";
String reply = gateway.sendAndReceive(requestXml);
System.out.println(reply);
}

Jetty websocket class loading issue

I have implemented a basic websocket server in Jetty(Standalone mode).
MyWebSocketServlet.java
public class MyWebSocketServlet extends WebSocketServlet {
#Override
public void configure(WebSocketServletFactory webSocketServletFactory){
webSocketServletFactory.getPolicy().setIdleTimeout(1000 * 10 * 60);
webSocketServletFactory.setCreator(new MyWebSocketFactory());
}
}
MyWebSocketFactory.java
public class MyWebSocketFactory implements WebSocketCreator {
public Object createWebSocket(
ServletUpgradeRequest servletUpgradeRequest
, ServletUpgradeResponse servletUpgradeResponse) {
return new MyWebSocketListener();
}
}
MyWebSocketListener.java
public class MyWebSocketListener implements WebSocketListener {
private Session sessionInstance;
public void onWebSocketBinary(byte[] bytes, int i, int i1) {
ByteBuffer data = ByteBuffer.wrap(bytes, i, i1);
try {
sessionInstance.getRemote().sendBytes(data);
} catch (IOException e) {
e.printStackTrace();
}
}
public void onWebSocketClose(int i, String s) {
}
public void onWebSocketConnect(Session session) {
sessionInstance = session;
}
public void onWebSocketError(Throwable throwable) {
throwable.printStackTrace(System.err);
}
public void onWebSocketText(String s) {
try {
sessionInstance.getRemote().sendString(s);
} catch (IOException e) {
e.printStackTrace();
}
}
}
web.xml
<?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"
metadata-complete="false"
version="3.1">
<servlet>
<servlet-name>WsEcho</servlet-name>
<servlet-class>org.test.sanket.MyWebSocketServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>WsEcho</servlet-name>
<url-pattern>/echo/*</url-pattern>
</servlet-mapping>
<servlet>
<servlet-name>HttpEcho</servlet-name>
<servlet-class>org.test.sanket.MyHttpServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>HttpEcho</servlet-name>
<url-pattern>/httpecho/*</url-pattern>
</servlet-mapping>
</web-app>
Instead of using a Standalone Jetty if I use embedded jetty and programatically configure the server and add the Servlets then this sample runs fine.
But if I am packaging the same as a war, and then deploying the same in a standalone jetty instance I am having the following observation:
I am able to hit the HttpServlet , i.e. MyHttpServlet and receive a response
But when I try to hit the websocket servlet, i.e. MyWebSocketServlet, I am seeing the following error:
exception
java.lang.ClassCastException: org.eclipse.jetty.server.HttpConnection cannot be cast to org.eclipse.jetty.server.HttpConnection
at org.eclipse.jetty.websocket.server.WebSocketServerFactory.acceptWebSocket(WebSocketServerFactory.java:175)
at org.eclipse.jetty.websocket.server.WebSocketServerFactory.acceptWebSocket(WebSocketServerFactory.java:148)
at org.eclipse.jetty.websocket.servlet.WebSocketServlet.service(WebSocketServlet.java:151)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:790)
at org.eclipse.jetty.servlet.ServletHolder.handle(ServletHolder.java:751)
at org.eclipse.jetty.servlet.ServletHandler.doHandle(ServletHandler.java:566)
at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:143)
at org.eclipse.jetty.security.SecurityHandler.handle(SecurityHandler.java:578)
at org.eclipse.jetty.server.session.SessionHandler.doHandle(SessionHandler.java:221)
at org.eclipse.jetty.server.handler.ContextHandler.doHandle(ContextHandler.java:1111)
I did come across the following link:
Jetty - stand alone WebSocket server
From the above link it seems to be a class loading issue, because jetty websocket package is treated as system class package and shouldn't be loaded by the WebApp if already loaded by the system.
So as referenced in the above link, I looked into the details suggested at:
http://www.eclipse.org/jetty/documentation/9.2.10.v20150310/jetty-classloading.html
From this link, one of the ways to get around this issue is to call the org.eclipse.jetty.webapp.WebAppContext.setSystemClasses(String Array) or org.eclipse.jetty.webapp.WebAppContext.addSystemClass(String) to allow fine control over which classes are considered System classes.
So for being able to do that, I should be able to get an Instance of WebAppContext, when Jetty is initializing and add the WebSocket classes as system classes.
I tried searching for how one would be able to achieve the same but no luck so far ? Can anybody kindly point me to a reference implementation as to how this can be achieved ?
Java Version: OpenJDK 7(latest)
Jetty: 9.2.10.v20150310
Operating System: Ubuntu 14.04
Thanks in advance!
If you have followed this link to setup the Jetty Standalone Instance, then you might have run the following command:
[/opt/web/mybase]# java -jar /opt/jetty/jetty-distribution-9.2.10.v20150310/start.jar --add-to-start=deploy,http,logging
If so, then when you try to hit the websocket servlet you will see the exception that you are noticing.
All you need to do is, instead of that command, you as well need to initialize the websocket module as shown below:
[/opt/web/mybase]# java -jar /opt/jetty/jetty-distribution-9.2.10.v20150310/start.jar --add-to-start=deploy,http,logging,websocket
Hope this helps!
Don't include the org.eclipse.jetty.* classes in your war's WEB-INF/lib or WEB-INF/classes directories.

Jetty - stand alone WebSocket server

in these days I try to implement a WebSocket server by using Jetty.
I've created a Jetty project called "WebSocketServer" as demo-base in the distribution of Jetty 9.2.0.v20140526.
After that, I write some codes to implement the WebSocket mechanism and export all codes to a war file to push it to the webapps folder of "WebSocketServer". When I java -jar ..<jetty.home>/start.jar, it is all workable. But, after I create a new connection to this WebSocket project, there are some error codes happened.
java.lang.ClassCastException: org.eclipse.jetty.server.HttpConnection cannot be cast to org.eclipse.jetty.server.HttpConnection
at org.eclipse.jetty.websocket.server.WebSocketServerFactory.acceptWebSocket(WebSocketServerFactory.java:175)
at org.eclipse.jetty.websocket.server.WebSocketServerFactory.acceptWebSocket(WebSocketServerFactory.java:148)
at org.eclipse.jetty.websocket.servlet.WebSocketServlet.service(WebSocketServlet.java:151)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:790)
at org.eclipse.jetty.servlet.ServletHolder.handle(ServletHolder.java:751)
at org.eclipse.jetty.servlet.ServletHandler.doHandle(ServletHandler.java:566)
at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:143)
at org.eclipse.jetty.security.SecurityHandler.handle(SecurityHandler.java:578)
at org.eclipse.jetty.server.session.SessionHandler.doHandle(SessionHandler.java:221)
at org.eclipse.jetty.server.handler.ContextHandler.doHandle(ContextHandler.java:1111)
at org.eclipse.jetty.servlet.ServletHandler.doScope(ServletHandler.java:498)
at org.eclipse.jetty.server.session.SessionHandler.doScope(SessionHandler.java:183)
at org.eclipse.jetty.server.handler.ContextHandler.doScope(ContextHandler.java:1045)
at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:141)
at org.eclipse.jetty.server.handler.ContextHandlerCollection.handle(ContextHandlerCollection.java:199)
at org.eclipse.jetty.server.handler.HandlerCollection.handle(HandlerCollection.java:109)
at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:98)
at org.eclipse.jetty.server.Server.handle(Server.java:461)
at org.eclipse.jetty.server.HttpChannel.handle(HttpChannel.java:284)
at org.eclipse.jetty.server.HttpConnection.onFillable(HttpConnection.java:244)
at org.eclipse.jetty.io.AbstractConnection$2.run(AbstractConnection.java:534)
at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:607)
at org.eclipse.jetty.util.thread.QueuedThreadPool$3.run(QueuedThreadPool.java:536)
at java.lang.Thread.run(Thread.java:744)
I have no idea what's going on? The following codes are what I write to build a simple WebSocket server.
Servlet:
#SuppressWarnings("serial")
public class XYZWebSocketServlet extends WebSocketServlet{
#Override
public void configure(WebSocketServletFactory factory) {
factory.getPolicy().setIdleTimeout(600000);
factory.register(XYZWebSocketEvent.class);
}
}
Event:
#WebSocket
public class XYZWebSocketEvent {
private Session session;
#OnWebSocketConnect
public void onConnect(Session sess) {
session = sess;
// Get parameters while client connect to server
Map<String,List<String>> parameters = session.getUpgradeRequest().getParameterMap();
String encyptedID = parameters.get("ID").get(0);
System.out.println("Connect: " + session.getRemoteAddress().getPort());
try {
session.setIdleTimeout(600000);
session.getRemote().sendString("Hello!");
} catch (IOException ioe) {
ioe.printStackTrace();
}
}
#OnWebSocketMessage
public void onMessage(String message) {
try {
session.getRemote().sendString("Message: " + message);
}
catch (Exception ex) {
}
}
#OnWebSocketClose
public void onClose(int statusCode, String reason) {
try {
session.getRemote().sendString("Close: statusCode=" + statusCode + ", reason=" +reason);
}
catch (Exception ex) {
}
}
#OnWebSocketError
public void onError(Throwable t) {
System.out.println("Error: " + t.getMessage());
}
public Session getSession() {
return this.session;
}
}
web.xml:
<?xml version="1.0" encoding="UTF-8"?>
<web-app>
<display-name>WebSocket application</display-name>
<servlet>
<servlet-name>XYZWebSocketServlet</servlet-name>
<servlet-class>com.newKinpo.servlet.XYZWebSocketServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>XYZWebSocketServlet</servlet-name>
<url-pattern>/events/*</url-pattern>
</servlet-mapping>
</web-app>
Is there something wrong? Thanks for your attention.
I had similiar problem and I have found the cause and the solution. Embeded jetty server is loaded by SUN class loader (will call it system class loader later) after webapp directory is scanned my app is loaded by WebApp class loader and when it comes to WebSocketServerFactory it is loaded by WebApp. However org.eclipse.jetty.server.HttpConnection object obtained from the request is loaded by the system class loader.
According to https://wiki.eclipse.org/Jetty/Reference/Jetty_Classloading jetty websocket package is treated as system class package and shouldn't be loaded by the WebApp if already loaded by the system.
The solution is to force loading of the package org.eclipse.jetty.websocket at the time jetty server is initialized.
I just create dummy instance of WebSocketHandler for example. There are many options to force package loading but they are irrelevant to this question.

Difference between Spring request scope and JSF request scope?

I am working on a JSR-286 portlet application that uses JSF 1.2. I am working on moving my JSF managed beans to Spring beans, and I noticed what appears to a difference between how Spring is treating request scope from how JSF is treating request scope.
In my portlet application, I have two portlets that live on the same page and both use the same starting JSF portlet page view. When I use JSF managed request beans, there is an individual request bean created for each portlet, which is the behavior I am looking for. When I use Spring beans, only one request bean is created and is shared among both portlets. Is this normal behavior? Is there any way I can stop it from doing this?
My original faces-config.xml file, before moving my beans to Spring:
<?xml version="1.0" encoding="UTF-8"?>
<faces-config
xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-facesconfig_1_2.xsd"
version="1.2">
<application>
<state-manager>com.ibm.faces.application.DevelopmentStateManager</state-manager>
<variable-resolver>com.ibm.faces.portlet.PortletVariableResolver</variable-resolver>
</application>
<factory>
<faces-context-factory>com.ibm.faces.context.AjaxFacesContextFactory</faces-context-factory>
<render-kit-factory>com.ibm.faces.renderkit.AjaxRenderKitFactory</render-kit-factory>
</factory>
<managed-bean>
<managed-bean-name>sessionBean</managed-bean-name>
<managed-bean-class>sanitycheck.SessionBean</managed-bean-class>
<managed-bean-scope>session</managed-bean-scope>
</managed-bean>
<managed-bean>
<managed-bean-name>pc_SanityCheckProjectView</managed-bean-name>
<managed-bean-class>sanitycheck.SanityCheckProjectView</managed-bean-class>
<managed-bean-scope>request</managed-bean-scope>
<managed-property>
<property-name>sessionBean</property-name>
<value>#{sessionBean}</value>
</managed-property>
</managed-bean>
<lifecycle>
<phase-listener>com.ibm.faces.webapp.ValueResourcePhaseListener</phase-listener>
</lifecycle>
</faces-config>
My faces-config.xml file after moving beans to Spring:
<?xml version="1.0" encoding="UTF-8"?>
<faces-config
xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-facesconfig_1_2.xsd"
version="1.2">
<application>
<state-manager>com.ibm.faces.application.DevelopmentStateManager</state-manager>
<variable-resolver>com.ibm.faces.portlet.PortletVariableResolver</variable-resolver>
<variable-resolver>org.springframework.web.jsf.DelegatingVariableResolver</variable-resolver>
</application>
<factory>
<faces-context-factory>com.ibm.faces.context.AjaxFacesContextFactory</faces-context-factory>
<render-kit-factory>com.ibm.faces.renderkit.AjaxRenderKitFactory</render-kit-factory>
</factory>
<lifecycle>
<phase-listener>com.ibm.faces.webapp.ValueResourcePhaseListener</phase-listener>
</lifecycle>
</faces-config>
And my spring-web.xml file:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.0.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.0.xsd">
<bean id="sessionBean" class="sanitycheck.SessionBean" scope="session">
<aop:scoped-proxy/>
</bean>
<bean id="pc_SanityCheckProjectView" class="pagecode.SanityCheckProjectView" scope="request" init-method="init">
<aop:scoped-proxy/>
<property name="sessionBean" ref="sessionBean"/>
</bean>
</beans>
I can provide my other files if necessary, just let me know. Thanks!
Edit: Added aop:scoped-proxy to the Spring beans.
Edit: Adding portlet.xml file:
<?xml version="1.0" encoding="UTF-8"?>
<portlet-app xmlns="http://java.sun.com/xml/ns/portlet/portlet-app_2_0.xsd" version="2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/portlet/portlet-app_2_0.xsd http://java.sun.com/xml/ns/portlet/portlet-app_2_0.xsd" id="com.ibm.faces.portlet.FacesPortlet.3a22ca3014">
<portlet>
<portlet-name>SanityCheckProject</portlet-name>
<display-name xml:lang="en">SanityCheckProject</display-name>
<display-name>SanityCheckProject</display-name>
<portlet-class>com.ibm.faces.portlet.FacesPortlet</portlet-class>
<init-param>
<name>com.ibm.faces.portlet.page.view</name>
<value>/SanityCheckProjectView.jsp</value>
</init-param>
<init-param>
<name>whichOne</name>
<value>Portlet1</value>
</init-param>
<init-param>
<name>wps.markup</name>
<value>html</value>
</init-param>
<expiration-cache>0</expiration-cache>
<supports>
<mime-type>text/html</mime-type>
<portlet-mode>view</portlet-mode>
</supports>
<supported-locale>en</supported-locale>
<resource-bundle>com.ibm.sanitycheckproject.nl.SanityCheckProjectPortletResource</resource-bundle>
<portlet-info>
<title>SanityCheckProject</title>
<short-title>SanityCheckProject</short-title>
<keywords>SanityCheckProject</keywords>
</portlet-info>
</portlet>
<portlet>
<portlet-name>SanityCheckPortlet2</portlet-name>
<display-name xml:lang="en">SanityCheckPortlet2</display-name>
<display-name>SanityCheckPortlet2</display-name>
<portlet-class>com.ibm.faces.portlet.FacesPortlet</portlet-class>
<init-param>
<name>com.ibm.faces.portlet.page.view</name>
<value>/SanityCheckProjectView.jsp</value>
</init-param>
<init-param>
<name>whichOne</name>
<value>Portlet2</value>
</init-param>
<init-param>
<name>wps.markup</name>
<value>html</value>
</init-param>
<expiration-cache>0</expiration-cache>
<supports>
<mime-type>text/html</mime-type>
<portlet-mode>view</portlet-mode>
</supports>
<supported-locale>en</supported-locale>
<resource-bundle>com.ibm.sanitycheckproject.nl.SanityCheckPortlet2PortletResource</resource-bundle>
<portlet-info>
<title>SanityCheckPortlet2</title>
<short-title>SanityCheckPortlet2</short-title>
<keywords>SanityCheckPortlet2</keywords>
</portlet-info>
</portlet>
<default-namespace>http://SanityCheckProject/</default-namespace>
</portlet-app>
In Spring XML config, you must use the <aop:scoped-proxy/> tag.
http://static.springsource.org/spring/docs/3.0.x/reference/beans.html#beans-factory-scopes-other-injection
<!-- an HTTP Session-scoped bean exposed as a proxy -->
<bean id="userPreferences" class="com.foo.UserPreferences" scope="session">
<!-- this next element effects the proxying of the surrounding bean -->
<aop:scoped-proxy/>
</bean>
I don't know if this was the best or even a very good solution, but what I eventually did was create two custom portlet scopes, one for request scope, and one for session scope. Essentially what my custom scopes do is that they prefix the name of the object requested with the portlet's namespace, which seems to keep everything separated.
Here is the code I used for my scopes:
Request Scope:
import javax.faces.context.FacesContext;
import org.springframework.beans.factory.ObjectFactory;
import org.springframework.web.context.request.RequestScope;
import com.ibm.faces.portlet.httpbridge.ActionResponseWrapper;
import javax.portlet.RenderResponse;
import javax.portlet.filter.RenderResponseWrapper;
public class PortletRequestScope extends RequestScope {
#Override
public Object get(String name, ObjectFactory objectFactory) {
Object response = FacesContext.getCurrentInstance().getExternalContext().getResponse();
if (response instanceof RenderResponse) {
String namespace=((RenderResponse)FacesContext.getCurrentInstance().getExternalContext().getResponse()).getNamespace();
return super.get(namespace + name, objectFactory);
}
else if (response instanceof RenderResponseWrapper) {
String namespace=((RenderResponseWrapper)FacesContext.getCurrentInstance().getExternalContext().getResponse()).getNamespace();
return super.get(namespace + name, objectFactory);
}
else if (response instanceof ActionResponseWrapper) {
String namespace=((ActionResponseWrapper)FacesContext.getCurrentInstance().getExternalContext().getResponse()).getNamespace();
return super.get(namespace + name, objectFactory);
}
else {
writeError(response);
}
return super.get(name, objectFactory);
}
#Override
public void registerDestructionCallback(String name, Runnable callback) {
Object response = FacesContext.getCurrentInstance().getExternalContext().getResponse();
if (response instanceof RenderResponse) {
String namespace=((RenderResponse)FacesContext.getCurrentInstance().getExternalContext().getResponse()).getNamespace();
super.registerDestructionCallback(namespace+name, callback);
}
else if (response instanceof RenderResponseWrapper) {
String namespace=((RenderResponseWrapper)FacesContext.getCurrentInstance().getExternalContext().getResponse()).getNamespace();
super.registerDestructionCallback(namespace+name, callback);
}
else if (response instanceof ActionResponseWrapper) {
String namespace=((ActionResponseWrapper)FacesContext.getCurrentInstance().getExternalContext().getResponse()).getNamespace();
super.registerDestructionCallback(namespace+name, callback);
}
else {
writeError(response);
}
super.registerDestructionCallback(name, callback);
}
#Override
public Object remove(String name) {
Object response = FacesContext.getCurrentInstance().getExternalContext().getResponse();
if (response instanceof RenderResponse) {
String namespace=((RenderResponse)FacesContext.getCurrentInstance().getExternalContext().getResponse()).getNamespace();
return super.remove(namespace+name);
}
else if (response instanceof RenderResponseWrapper) {
String namespace=((RenderResponseWrapper)FacesContext.getCurrentInstance().getExternalContext().getResponse()).getNamespace();
return super.remove(namespace+name);
}
else if (response instanceof ActionResponseWrapper) {
String namespace=((ActionResponseWrapper)FacesContext.getCurrentInstance().getExternalContext().getResponse()).getNamespace();
return super.remove(namespace+name);
}
else {
writeError(response);
}
return super.remove(name);
}
protected void writeError(Object response) {
System.err.println("Error in PortletRequestScope");
System.err.println("Response is unrecognized class: " + response.getClass().getCanonicalName());
System.err.println("Please modify code to handle class");
}
}
Session Scope:
import javax.faces.context.FacesContext;
import org.springframework.beans.factory.ObjectFactory;
import org.springframework.web.context.request.SessionScope;
import com.ibm.faces.portlet.httpbridge.ActionResponseWrapper;
import javax.portlet.RenderResponse;
import javax.portlet.filter.RenderResponseWrapper;
public class PortletSessionScope extends SessionScope {
#Override
public Object get(String name, ObjectFactory objectFactory) {
Object response = FacesContext.getCurrentInstance().getExternalContext().getResponse();
if (response instanceof RenderResponse) {
String namespace=((RenderResponse)FacesContext.getCurrentInstance().getExternalContext().getResponse()).getNamespace();
return super.get(namespace + name, objectFactory);
}
else if (response instanceof RenderResponseWrapper) {
String namespace=((RenderResponseWrapper)FacesContext.getCurrentInstance().getExternalContext().getResponse()).getNamespace();
return super.get(namespace + name, objectFactory);
}
else if (response instanceof ActionResponseWrapper) {
String namespace=((ActionResponseWrapper)FacesContext.getCurrentInstance().getExternalContext().getResponse()).getNamespace();
return super.get(namespace + name, objectFactory);
}
else {
writeError(response);
}
return super.get(name, objectFactory);
}
#Override
public void registerDestructionCallback(String name, Runnable callback) {
Object response = FacesContext.getCurrentInstance().getExternalContext().getResponse();
if (response instanceof RenderResponse) {
String namespace=((RenderResponse)FacesContext.getCurrentInstance().getExternalContext().getResponse()).getNamespace();
super.registerDestructionCallback(namespace+name, callback);
}
else if (response instanceof RenderResponseWrapper) {
String namespace=((RenderResponseWrapper)FacesContext.getCurrentInstance().getExternalContext().getResponse()).getNamespace();
super.registerDestructionCallback(namespace+name, callback);
}
else if (response instanceof ActionResponseWrapper) {
String namespace=((ActionResponseWrapper)FacesContext.getCurrentInstance().getExternalContext().getResponse()).getNamespace();
super.registerDestructionCallback(namespace+name, callback);
}
else {
writeError(response);
}
super.registerDestructionCallback(name, callback);
}
#Override
public Object remove(String name) {
Object response = FacesContext.getCurrentInstance().getExternalContext().getResponse();
if (response instanceof RenderResponse) {
String namespace=((RenderResponse)FacesContext.getCurrentInstance().getExternalContext().getResponse()).getNamespace();
return super.remove(namespace+name);
}
else if (response instanceof RenderResponseWrapper) {
String namespace=((RenderResponseWrapper)FacesContext.getCurrentInstance().getExternalContext().getResponse()).getNamespace();
return super.remove(namespace+name);
}
else if (response instanceof ActionResponseWrapper) {
String namespace=((ActionResponseWrapper)FacesContext.getCurrentInstance().getExternalContext().getResponse()).getNamespace();
return super.remove(namespace+name);
}
else {
writeError(response);
}
return super.remove(name);
}
protected void writeError(Object response) {
System.err.println("Error in PortletSessionScope");
System.err.println("Response is unrecognized class: " + response.getClass().getCanonicalName());
System.err.println("Please modify code to handle class");
}
}
Then, in my spring-web.xml, I defined my custom scopes:
<bean class="org.springframework.beans.factory.config.CustomScopeConfigurer">
<property name="scopes">
<map>
<entry key="portletRequestScope">
<bean class="com.test.scope.PortletRequestScope"/>
</entry>
<entry key="portletSessionScope">
<bean class="com.test.portlet.scope.PortletSessionScope"/>
</entry>
</map>
</property>
</bean>
And when I defined my actual Spring beans, I used my custom scopes instead of the regular scope -- for example:
<bean id="sessionBean" class="com.test.managedbeans.SessionBean"
scope="portletSessionScope" lazy-init="true"/>
At the very least, doing this seemed to work in my specific situation of JSF + Spring on WebSphere Portal, and hopefully this will be useful to someone else.

Internalization of JSF project on WebSphere 7

I'm trying to implement loading Resource Bundles for JSF application from DB, following the sample: internationalization in JSF with ResourceBundle entries which are loaded from database
For the test I coded getItSomehow() just as create HashMap and fill it with key "hello_world" and value "["+locale+"]"+"hello world"
The sample works fine when I deploy it on Glassfish3.
But when I use WebSphere AS 7, the jsf page is displayed correctly only for the first time. Opening the jsf page in other browsers (with other prefered language selected) I receive the respond always in the locale of first run.
While debugging, I found the difference in implementation of ResourceBundle.java: Glassfish uses this class provided in rt.jar of the JDK1.6; but WebSphere has this class inside java.util.jar
The ResourceBundle (of WebSphere) called from ApplicationResourceBundle.getResourceBundle() calls handleGetBundle() and finally invokes my.i18n.DbResourceBundle$DBControl.newBundle() .
Called second (and further) time with different locale it doesn't invoke my override but just returns the same bundle created for first locale.
The question: is it possible to code internalizable jsf web-application deployed on WebSphere AS 7.0.07, not digging nor hacking into internals of the AS?
(environment: Windows XP, WebSphere AS 7.0.0.7, jdk1.6.0_24, jsf 2.1.4)
You can provide a specific implementation of ResourceBundle.
Here an example that gets the current locale each time JSF invokes the ResourceBundle methods:
package my.company.jsf.util;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Locale;
import java.util.Map;
import java.util.ResourceBundle;
import javax.faces.context.FacesContext;
public class MyBundle extends ResourceBundle {
private static final Map<Locale, ResourceBundle> RB_CACHE = new HashMap<Locale, ResourceBundle>();
private static final String BUNDLE_NAME = "my-messages";
public MyBundle() {
}
#Override
public Enumeration<String> getKeys() {
ResourceBundle rb = getResourceBundle();
final Iterator<String> it = rb.keySet().iterator();
return new Enumeration<String>() {
#Override
public boolean hasMoreElements() {
return it.hasNext();
}
#Override
public String nextElement() {
return it.next();
}
};
}
#Override
protected Object handleGetObject(String key) {
ResourceBundle rb = getResourceBundle();
return rb.getObject(key);
}
private ResourceBundle getResourceBundle() {
Locale locale = FacesContext.getCurrentInstance().getViewRoot().getLocale();
ResourceBundle rb = RB_CACHE.get(locale);
if (rb == null) {
rb = ResourceBundle.getBundle(BUNDLE_NAME, locale);
RB_CACHE.put(locale, rb);
}
return rb;
}
}
and in your faces-config.xml put:
<?xml version="1.0" encoding="UTF-8"?>
<faces-config version="2.0" xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xi="http://www.w3.org/2001/XInclude" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-facesconfig_2_0.xsd">
<application>
<resource-bundle>
<base-name>my.company.jsf.util.MyBundle</base-name>
<var>MSG</var>
</resource-bundle>
</application>
</faces-config>
We had your same problem and this solution worked for us with Windows Server 2008, WebSphere AS 7.0.0.19, jdk1.6.0_29, jsf 2.1.5

Resources