Migrate Cometd 2 to Cometd3 in Glassfish- Handshake fail - servlets

I migrated my cometd from 2 to 3 and come across some problem:
Handshake never succeed, and there's no error messages.
I tried all I can do but still in vain.
Here's my Code:
ConfigurationServlet:
#Override
public void init() throws ServletException {
logger.info("start prepare echoService...");
// Grab the Bayeux object
BayeuxServer bayeuxServer = (BayeuxServer) getServletContext().getAttribute(BayeuxServer.ATTRIBUTE);
bayeuxServer.createChannelIfAbsent(NODE_CHANNEL, new ServerChannel.Initializer() { //1030829 change createIfAbsend to createChannelIfAbsent
#Override
public void configureChannel(ConfigurableServerChannel channel) {
channel.setPersistent(true);
}
});
EchoService echoService = new EchoService(bayeuxServer);
logger.info("...prepare echoService done");
}
EchoService:
public EchoService(BayeuxServer bayeuxServer) {
super(bayeuxServer, "echo");
//for what?
logger.info("=============enter echoService constructor=============");
addService("/echo", "processEcho");
addService(CometdProperties.COMETD_CHANNEL_WEB, "processReq");
logger.info("=============leaving echoService constructor=============");
isEchoServiceStarted = true;
}
public void processEcho(ServerSession remote, ServerMessage message) {
remote.deliver(getServerSession(), "/echo", message.getData());
}
public void processReq(ServerSession remote, ServerMessage message) {
//do something...
}
InitConnect in my client:
public boolean initConnect(String channel, ClientSessionChannel.MessageListener ml) {
HClogger.info("=============initConnect=============Listener:" + ml);
HttpClient httpClient = new HttpClient();
try {
httpClient.start();
} catch (Exception ex) {
HClogger.error(ex.toString());
if(connCnt<10){//Retry 9 times.
connCnt++;
return initConnect(channel,ml);
}
return false;
}
HClogger.info("*********************************try connect to server...");
Map<String, Object> options = new HashMap<>();
ClientTransport longPool = new LongPollingTransport(options, httpClient);
bayeuxClient = new BayeuxClient(CometdProperties.COMETD_DEFAULTURL, longPool);
bayeuxClient.handshake();
boolean handshaken = bayeuxClient.waitFor(10000, BayeuxClient.State.CONNECTED);
if (handshaken) {
HClogger.info("connected to server ok...");
bayeuxClient.getChannel(channel).subscribe(ml);
HClogger.info("subscribed to " + channel + " channel.");
try {
Thread.sleep(2000);
} catch (InterruptedException ex) {
HClogger.error("Error when sleep after subscribe.", ex);
}
HClogger.info("=============HandleClient subscribe done.=============");
return true;
} else {
HClogger.info("=============HandleClient handshake fail.=============");
if(connCnt<10){//Retry 9 times.
connCnt++;
return initConnect(channel,ml);
}
return false;
}
}
Web.xml:
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="3.1" 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">
<context-param>
<param-name>javax.faces.PROJECT_STAGE</param-name>
<param-value>Development</param-value>
</context-param>
<servlet>
<servlet-name>cometd</servlet-name>
<servlet-class>org.cometd.server.CometDServlet</servlet-class>
<init-param>
<param-name>timeout</param-name>
<param-value>300000</param-value>
</init-param>
<load-on-startup>2</load-on-startup>
<async-supported>true</async-supported>
</servlet>
<servlet>
<servlet-name>ConfigurationServlet</servlet-name>
<servlet-class>org.astri.ims.ccs.webcommand.ConfigurationServlet</servlet-class>
<load-on-startup>3</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>ConfigurationServlet</servlet-name>
<url-pattern>/ConfigurationServlet</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>cometd</servlet-name>
<url-pattern>/cometd/*</url-pattern>
</servlet-mapping>
<session-config>
<session-timeout>
30
</session-timeout>
</session-config>
<welcome-file-list>
<welcome-file>faces/index.xhtml</welcome-file>
</welcome-file-list>
</web-app>
And here's what I add in my lib:
bayeux-api-3.0.1.jar
cometd-java-client-3.0.1.jar
cometd-java-common-3.0.1.jar
cometd-java-server-2.0.1.jar
jackson-mapper-asl-1.9.12.jar
javax.servlet-3.1.jar
jetty-client-9.2.2v20140723.jar
jetty-http-9.2.2v20140723.jar
jetty-io-9.2.2v20140723.jar
jetty-jmx-9.2.2v20140723.jar
jetty-server-9.2.2v20140723.jar
jetty-servlet-9.2.2v20140723.jar
jetty-util-9.2.2v20140723.jar
jetty-util-ajax-9.2.2v20140723.jar
Is there anything wrong in my code or configuration?
Update
I added a listener to the meta_channel, and I got this while handshaking:
{"id":"3","failure":{"message":{"id":"3","supportedConnectionTypes":["long-polling"],"channel":"/meta/handshake","version":"1.0"},"exception":"java.util.concurrent.TimeoutException: Total timeout elapsed","connectionType":"long-polling"},"subscription":null,"successful":false,"channel":"/meta/handshake"}

It turns out there is a bug in glassfish4.
Thanks for #sbordet who investigate and find out what's going on.
For detail information, please visit here.
For those who want to use CometD3, Jetty is suggested container.
For those who have no choice but to use glassfish, Cometd2.X works.
I've tried with cometd2.9.1, 3.0.0 and 3.0.1 in glassfish4, the result is
2.9.1 works in glassfish4 while 3.0.0 and 3.0.1 not.

Related

HTTP Status 405 – Method Not Allowed in Apache Tomcat Server [duplicate]

This question already has answers here:
HTTP Status 405 - HTTP method is not supported by this URL
(2 answers)
Closed 1 year ago.
I am encountering HTTP Status 405 – Method Not Allowed error in my Java Backend.
I am using Apache Tomcat Server
Type Status Report
Message HTTP method GET is not supported by this URL
Description The method received in the request-line is known by the origin server but not supported by the target resource.
Here is the screenshot:
My Web.xml file:
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://xmlns.jcp.org/xml/ns/javaee" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee
http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" id="WebApp_ID" version="3.1">
<display-name>Backend</display-name>
<welcome-file-list>
<welcome-file>index.html</welcome-file>
<welcome-file>index.htm</welcome-file>
<welcome-file>index.jsp</welcome-file>
<welcome-file>default.html</welcome-file>
<welcome-file>default.htm</welcome-file>
<welcome-file>default.jsp</welcome-file>
</welcome-file-list>
<filter>
<filter-name>CorsFilter</filter-name>
<filter-class>org.apache.catalina.filters.CorsFilter</filter-class>
<init-param>
<param-name>cors.allowed.origins</param-name>
<param-value>http://localhost:3000</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>CorsFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<servlet>
<servlet-name>BatchDisplay</servlet-name>
<servlet-class>com.hello.BatchDisplay</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>BatchDisplay</servlet-name>
<url-pattern>/BatchDisplay.do</url-pattern>
</servlet-mapping>
<servlet>
<servlet-name>AddServlet</servlet-name>
<servlet-class>com.hello.AddServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>AddServlet</servlet-name>
<url-pattern>/AddServlet.do</url-pattern>
</servlet-mapping>
</web-app>
When I am executing Post request from Postman, I am getting this error.
My Java backend code:
package com.hello;
import java.io.*;
import java.sql.*;
import javax.servlet.ServletException;
import javax.servlet.http.*;
public class AddServelet extends HttpServlet {
private static final long serialVersionUID = 1L;
protected void doPost(HttpServletRequest request,HttpServletRequest response) throws ServletException
{
try {
String custNumber=request.getParameter("cust_number");
String nameCustomer=request.getParameter("name_customer");
String invoiceID=request.getParameter("invoice_id");
Double TotalOpenAmount=Double.parseDouble(request.getParameter("total_open_amount"));
String dueinDATE=request.getParameter("due_in_date");
String Notes=request.getParameter("notes");
System.out.print("Acquiring Connection");
Connection connection = DriverManager.getConnection("com.mysql.jdbc.Driver", "root", "abcd");
System.out.print("Connected Successfully");
String sql="INSERT INTO invoice
invoice_details(cust_number,name_customer,invoice_id,total_open_amount,due_in_date,notes)
VALUES (?,?,?,?,?,?)";
PreparedStatement statement = connection.prepareStatement(sql);
statement.setString(1, nameCustomer);
statement.setString(2, custNumber);
statement.setString(3, invoiceID);
statement.setDouble(4, TotalOpenAmount);
statement.setString(5, dueinDATE);
statement.setString(6, Notes);
statement.executeUpdate();
}
catch(SQLException e){
e.printStackTrace();
}
finally
{
}
}
}
I really don't know why is it giving such an error.
Please suggest me a way to debug it.
You need to override doGet method if u wanna call by GET method;
#Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
try {
String custNumber=request.getParameter("cust_number");
String nameCustomer=request.getParameter("name_customer");
String invoiceID=request.getParameter("invoice_id");
Double TotalOpenAmount=Double.parseDouble(request.getParameter("total_open_amount"));
String dueinDATE=request.getParameter("due_in_date");
String Notes=request.getParameter("notes");
System.out.print("Acquiring Connection");
Connection connection = DriverManager.getConnection("com.mysql.jdbc.Driver", "root", "abcd");
System.out.print("Connected Successfully");
String sql="INSERT INTO invoice
invoice_details(cust_number,name_customer,invoice_id,total_open_amount,due_in_date,notes)
VALUES (?,?,?,?,?,?)";
PreparedStatement statement = connection.prepareStatement(sql);
statement.setString(1, nameCustomer);
statement.setString(2, custNumber);
statement.setString(3, invoiceID);
statement.setDouble(4, TotalOpenAmount);
statement.setString(5, dueinDATE);
statement.setString(6, Notes);
statement.executeUpdate();
}
catch(SQLException e){
e.printStackTrace();
}
finally
{
}
}
When you need to use GET method: override doGet(HttpServletRequest request, HttpServletResponse response), POST- doPost(HttpServletRequest request, HttpServletResponse response), both - doGet and doPost

Eclipse: ServletConfig object returns NULL on calling getServletConfig()

this is my code . Please help me solve this problem . I m new to servlet and i m trying my best to solve it but i m unable .
public class InsertData extends GenericServlet{
public void service(ServletRequest request, ServletResponse response) throws ServletException, IOException {
PrintWriter pw = null ;
ServletConfig conf = getServletConfig(); // This is giving null everytime i m checked it in webpage
String str = cont.getInitParameter("username");
pw = response.getWriter();
pw.println("<html><body><b>conf</b></body><html>");
}
}
and this is my web.xml file :
<web-app>
<servlet>
<servlet-name>s1</servlet-name>
<servlet-class>InsertData</servlet-class>
<init-param>
<param-name>username</param-name>
<param-value>mydb</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>s1</servlet-name>
<url-pattern>/InsertData</url-pattern>
</servlet-mapping>
<welcome-file-list>
<welcome-file>home.html</welcome-file>
</welcome-file-list>
</web-app>

IllegalArgumentException: The servlets named [myservlet] and [MyServlet] are both mapped to the url-pattern [/MyServlet] which is not permitted [duplicate]

This question already has answers here:
java.lang.IllegalArgumentException: The servlets named [X] and [Y] are both mapped to the url-pattern [/url] which is not permitted
(7 answers)
Closed 7 years ago.
I wrote very simple dynamic web application in eclipse Mars(4.5.1) but i cannot start the tomcat server from eclipse. Below is the root cause of the error:
Caused by: java.lang.IllegalArgumentException: The servlets named [myservlet] and [MyServlet] are both mapped to the url-pattern [/MyServlet] which is not permitted
at org.apache.tomcat.util.descriptor.web.WebXml.addServletMapping(WebXml.java:308)
at org.apache.catalina.startup.ContextConfig.processAnnotationWebServlet(ContextConfig.java:2342)
at org.apache.catalina.startup.ContextConfig.processAnnotationsStream(ContextConfig.java:2024)
at org.apache.catalina.startup.ContextConfig.processAnnotationsWebResource(ContextConfig.java:1918)
at org.apache.catalina.startup.ContextConfig.webConfig(ContextConfig.java:1139)
at org.apache.catalina.startup.ContextConfig.configureStart(ContextConfig.java:771)
at org.apache.catalina.startup.ContextConfig.lifecycleEvent(ContextConfig.java:305)
at org.apache.catalina.util.LifecycleSupport.fireLifecycleEvent(LifecycleSupport.java:95)
at org.apache.catalina.util.LifecycleBase.fireLifecycleEvent(LifecycleBase.java:90)
at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5154)
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150)
... 6 more
I followed this steps- addeding libraries in Properties -> Java Build Path -> Add Libraries -> Server runtime -> Apache. After that i added Windows -> Preferences -> Serevr -> Runtime Environments -> Apache. Tomcat v8.0 Server is perfectly starting from **C:\Program Files\Apache Software Foundation\Tomcat 8.0\bin **.
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" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" id="WebApp_ID" version="3.0">
<display-name>2J2EEProcessingFromData</display-name>
<servlet>
<servlet-name>myservlet</servlet-name>
<servlet-class>Testing</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>myservlet</servlet-name>
<url-pattern>/MyServlet</url-pattern>
</servlet-mapping>
<welcome-file-list>
<welcome-file>index.html</welcome-file>
<welcome-file>index.htm</welcome-file>
<welcome-file>index.jsp</welcome-file>
<welcome-file>default.html</welcome-file>
<welcome-file>default.htm</welcome-file>
<welcome-file>default.jsp</welcome-file>
</welcome-file-list>
</web-app>
MyServlrt.java
public class MyServlet extends HttpServlet {
protected void processRequest(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException{
response.setContentType("text/html;charset=ISO-8859-1");
PrintWriter pw = response.getWriter();
try{
String username = request.getParameter("username");
String password = request.getParameter("pass");
pw.write("Hello "+username);
pw.write("Your password is:"+password);
} catch(Exception e){
e.printStackTrace();
} finally {
pw.close();
}
}
#Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException{
PrintWriter pw = response.getWriter();
pw.write("doGet called");
processRequest(request, response);
}
#Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException{
PrintWriter pw = response.getWriter();
pw.write("doPost called");
processRequest(request, response);
}
#Override
public String getServletInfo(){
return "Shord description";
}
}
Click on Servers Tab double-click on Tomcat then change HTTP port in Ports section to any others .
or Open Server.xml file and change Connector Port . Restart the Server and then Check
It's funny because i'm answering my own question i replaced url-pattern with (.java) extension as below.
<url-pattern>/MyServlet.java</url-pattern>
<url-pattern>/MyServlet</url-pattern>

TaskExecutor in Spring MVC is not asynchronous

The workmanager is defined in admin console with minimum 1 and 5 as pool size. the web app is with following configurations.
Web.xml
<web-app id="RestController" metadata-complete="true" version="3.0" 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-app_3_0.xsd">
<servlet>
<servlet-name>rest-controller</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>rest-controller</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
</web-app>
Application-Context.xml
`<!-- Empty. I moved all the servlet related entities from here -->`
rest-Controller-servlet.xml
<context:component-scan base-package="com.package.main-pack" />
<task:annotation-driven executor="taskExecutor"/>
<mvc:annotation-driven />
<task:executor id="taskExecutor" pool-size="5" />
RestController.java
#RequestMapping(value = "/reportFake", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE)
#ResponseBody
#Override
public List<String> searchFake() {
List<String> stringArr = new ArrayList<String>();
for (String folder : foldername) {
Future<String> result = reportLookup.doParallelFake(folder);
try {
while (true) {
if (result.isDone()) {
stringArr.add(result.get());
Logger.debug(RestController.class,
"Executed and Returned");
break;
}
}
} catch (InterruptedException e) {
Logger.error(RestController.class, e.getMessage());
} catch (ExecutionException e) {
Logger.error(RestController.class, e.getMessage());
}
}
return stringArr;
}
ReportLookupExecutor.java
#Service("reportLookup")
public class ReportLookupExecutor implements ReportLookupIntf {
#Async("taskExecutor")
#Async("taskExecutor")
#Override
public Future<String> doParallelFake(String folder) {
logger.debug("Execute method asynchronously - "
+ Thread.currentThread().getName());
try {
Thread.sleep(5000);
return new AsyncResult<String>("Folder Name :: " + folder);
} catch (InterruptedException e) {
logger.error(e);
}
return null;
}
Output
[11/4/15 12:41:24:349 EST] 0000014d SystemOut O [DEBUG] 04 Nov 12:41:24 PM taskExecutor-1 Execute method asynchronously - taskExecutor-1
[11/4/15 12:41:29:365 EST] 0000007b SystemOut O [DEBUG] 04 Nov 12:41:29 PM WebContainer : 3 Executed and Returned
[11/4/15 12:41:29:366 EST] 0000014e SystemOut O [DEBUG] 04 Nov 12:41:29 PM taskExecutor-2 Execute method asynchronously - taskExecutor-2
[11/4/15 12:41:34:365 EST] 0000007b SystemOut O [DEBUG] 04 Nov 12:41:34 PM WebContainer : 3 Executed and Returned
Now, I've tried to follow this link.
I manually threw an exception to check the stack-trace and found that it is being run by ibm.asynchbeans and is duly intercepted by Spring. Here is a snippet from the stack-trace.
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:60)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:37)
at java.lang.reflect.Method.invoke(Method.java:611)
at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:317)
at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:190)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:157)
at org.springframework.aop.interceptor.AsyncExecutionInterceptor$1.call(AsyncExecutionInterceptor.java:97)
at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:314)
at java.util.concurrent.FutureTask.run(FutureTask.java:149)
at org.springframework.scheduling.commonj.DelegatingWork.run(DelegatingWork.java:61)
at com.ibm.ws.asynchbeans.J2EEContext.run(J2EEContext.java:1178)
at com.ibm.ws.asynchbeans.WorkWithExecutionContextImpl.go(WorkWithExecutionContextImpl.java:199)
at com.ibm.ws.asynchbeans.CJWorkItemImpl.run(CJWorkItemImpl.java:236)
at com.ibm.ws.util.ThreadPool$Worker.run(ThreadPool.java:1862)
Would appreciate any help.
OK! Finally I was able to make it run. The solution is to make all the number of calls to the async method before getting the first value of future. I was able to do this by creating a List of Future objects. This is how the final calling class looks.
RestController.java
#RequestMapping(value = "/reportFake", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE)
#ResponseBody
#Override
public List<String> searchFake() throws InterruptedException,
ExecutionException {
List<Future<String>> futureArr = new ArrayList<Future<String>>();
for (String folder : new String[] { "One", "Two", "Three", "Four" }) {
futureArr.add(reportLookup.doParallelFake(folder));
}
List<String> stringArr = new ArrayList<String>();
for (Future<String> future : futureArr) {
stringArr.add(future.get());
}
return stringArr;
}

Issue with making a controller method asynchronous with Spring 3.2.RC2

I am trying to test the latest asynchronous feature of Spring MVC controllers but I have not been able to get it to work.
Here is the code for my async method:
#RequestMapping(value = "/hello")
public Callable<String> async(final Model model) {
System.out.println("entered async controller method");
return new Callable<String>() {
public String call() throws Exception {
Thread.sleep(2000L);
model.addAttribute("message", "asyncRequest dealt with");
System.out.println("about to return from call()");
return "hello";
}
};
}
Here is the relevant portion from web.xml:
<servlet>
<servlet-name>SpringMVC</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/spring/webmvc-config.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
<async-supported>true</async-supported>
</servlet>
However "about to return from call()" is never printed in the console and I never get to see such logs as this: 08:25:17 [MvcAsync1] WebAsyncManager - ...
in the console...
FYI, I use Spring 3.2.RC2
To further configure the async-support implement a AsyncTaskExecutor
By default Spring MVC uses a SimpleAsyncTaskExecutor to execute Callable instances returned by controller methods. For production you must replace it with an AsyncTaskExecutor implementation configured appropriately for your environment.
Create the AsyncTaskExecutor
<beans:bean id="asyncTaskExecutor" class="org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor">
<beans:property name="corePoolSize" value="5" />
<beans:property name="maxPoolSize" value="10" />
<beans:property name="queueCapacity" value="25" />
</beans:bean>
Then assign the task-executor
<mvc:annotation-driven >
<mvc:async-support default-timeout="30000" task-executor="asyncTaskExecutor" />
</mvc:annotation-driven>
http://blog.springsource.org/2012/05/10/spring-mvc-3-2-preview-making-a-controller-method-asynchronous/
I finally found why my sample was not working: one has to add the following to the web-mvc configuration file:
<mvc:annotation-driven>
<mvc:async-support default-timeout="3000"/>
</mvc:annotation-driven>
Hi doing a similar application with the following code :
public String doSlowWork() {
System.out.println("Start slow work");
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("finish slow work");
return "index"; // return view's name
}
returning index but not giving the log info of the method

Resources