SpringBoot Async requests throwing 503 Service Unavailable - asynchronous

I was experimenting with springboots async controllers when I came around with this issue.
I set the number of threads for the servlet container to 10 by setting the following
#Bean
public JettyEmbeddedServletContainerFactory jettyEmbeddedServletContainerFactory(#Value("${server.port:8080}") final String port,
#Value("${jetty.threadPool.maxThreads:10}") final String maxThreads,
#Value("${jetty.threadPool.minThreads:8}") final String minThreads,
#Value("${jetty.threadPool.idleTimeout:60000}") final String idleTimeout) {
final JettyEmbeddedServletContainerFactory factory = new JettyEmbeddedServletContainerFactory(Integer.valueOf(port));
factory.addServerCustomizers(new JettyServerCustomizer() {
#Override
public void customize(final Server server) {
final QueuedThreadPool threadPool = server.getBean(QueuedThreadPool.class);
threadPool.setMaxThreads(Integer.valueOf(maxThreads));
threadPool.setMinThreads(Integer.valueOf(minThreads));
threadPool.setIdleTimeout(Integer.valueOf(idleTimeout));
}
});
return factory;
}
I then configured the async thread pool to also start with 10 but set the max thread poolsize to 200.
#Bean
public Executor asyncExecutor() {
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
executor.setCorePoolSize(10);
executor.setMaxPoolSize(200);
executor.setQueueCapacity(500);
executor.setThreadNamePrefix("asyncthread-");
executor.initialize();
return executor;
}
When I submit 20 concurrent requests I get the below error consistently on the client code. The server side doesn't seem to show any issues.
08:06:12.550 [pool-1-thread-1] DEBUG
org.springframework.web.client.RestTemplate - GET request for
"http://localhost:8080/time/basicasync" resulted in 503 (Service
Unavailable); invoking error handler
java.util.concurrent.ExecutionException:
org.springframework.web.client.HttpServerErrorException: 503 Service
Unavailable at
java.util.concurrent.FutureTask.report(FutureTask.java:122) at
java.util.concurrent.FutureTask.get(FutureTask.java:192) at
Main.main(Main.java:64) Caused by:
org.springframework.web.client.HttpServerErrorException: 503 Service
Unavailable at
org.springframework.web.client.DefaultResponseErrorHandler.handleError(DefaultResponseErrorHandler.java:94)
at
org.springframework.web.client.RestTemplate.handleResponse(RestTemplate.java:641)
at
org.springframework.web.client.RestTemplate.doExecute(RestTemplate.java:597)
at
org.springframework.web.client.RestTemplate.execute(RestTemplate.java:557)
at
org.springframework.web.client.RestTemplate.getForEntity(RestTemplate.java:289)
at Main.lambda$main$1(Main.java:32) at
java.util.concurrent.FutureTask.run(FutureTask.java:266) at
java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
at java.util.concurrent.FutureTask.run(FutureTask.java:266) at
java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at
java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at java.lang.Thread.run(Thread.java:748)
My Client code hangs because I use CompletionService to submit all tasks. If I increase the async threadpool on the server to 50 the issue doesn't seem to occur. Can someone throw some light on this behavior ?

Related

How can i get logs/debugging for an error 500?

I'm working on a .NET Core 2.0 web application. I got a mocked database where application works good. Today i created a clean database and got this error 500 both on IIS Express and on regular IIS.
The thing is: i couldn't debug why is throwing the error 500. The application just run.
I've currently tried:
Check IIS logs by activating stdoutLogEnabled="true" and the only log created was:
Hosting environment: Production Content root path:
C:\Users\pistolon\Downloads\peto Now listening on:
http://localhost:13361 Application started. Press Ctrl+C to shut down.
Debugging from start the startup.cs file.
When I switch back to the mocked db it works without error.
Do you any of you could point me on where could i get an exception or log for this?
You can use Event Viewer or Visual Studio Remote Debugging to debug your deployed applications.
Also, you can use a logging framework like Serilog and use one of it sinks like file sink and create a middleware which catches and logs your exceptions and write their StackTrace, Message, Source to a log file that you can read them.
Here is ErrorHandlingMiddleware implementation :
public class ErrorHandlingMiddleware
{
readonly RequestDelegate _next;
static ILogger<ErrorHandlingMiddleware> _logger;
public ErrorHandlingMiddleware(RequestDelegate next,
ILogger<ErrorHandlingMiddleware> logger)
{
_next = next;
_logger = logger;
}
public async Task Invoke(HttpContext context)
{
try
{
await _next(context);
}
catch (Exception ex)
{
await HandleExceptionAsync(context, ex);
}
}
static async Task HandleExceptionAsync(
HttpContext context,
Exception exception)
{
string error = "An internal server error has occured.";
_logger.LogError($"{exception.Source} - {exception.Message} - {exception.StackTrace} - {exception.TargetSite.Name}");
context.Response.StatusCode = (int)HttpStatusCode.InternalServerError;
context.Response.ContentType = "application/json";
await context.Response.WriteAsync(JsonConvert.SerializeObject(new
{
error
}));
}
}
Usage :
app.UseMiddleware<ErrorHandlingMiddleware>();
I don't believe this is enough information to go off of, however if you're seeing that 500 error when using the real database and the mock database is working appropriately, I would bet that your issue is with the connection string. You can also check to ensure that you're in the development environment as well.
Update: You can also try to use app.UseDeveloperExceptionPage();

Asynchronous messaging in websphare 855 setmessagelistener

Hi am migrating my application from jrun to websphere server and it has functionality of asynchronous messaging usnig message listener.
public void startMessageListener(final String queueName,
final MessageListener listener) throws Exception {
QueueSession queueSession = createNewQueueSession();
Queue queue = (Queue) queueContext.lookup(queueName);
QueueReceiver queueReceiver = queueSession.createReceiver((queue));
queueReceiver.setMessageListener(listener);
//LOG Forging fix-Fortify Scan TTP 345546 -START
log.debug("started queue " + queueName);
//LOG Forging fix-Fortify Scan TTP 345546 -END
}
when i use same code in websphere it throws error javax.jms.IllegalStateException: Method setMessageListener not permitted
Because the JMS spec does not allow you to use this feature in a JEE Container.
Please help me to make it work with less code changes.

Spring Boot ErrorPageFilter block the custom exception handler with #ExceptionHandler

My web app constructed with SpringBoot 2.0.0.M3 and java8, deploy on outer tomcat/8.0.24 war.
My Exception handler:
#ControllerAdvice(annotations = RestController.class)
public class GlobalExceptionHandler extends
ResponseEntityExceptionHandler {
#ExceptionHandler(MyCustomException.class)
public ResponseEntity<String> handlerMyException(
MyCustomException rae) {
String msg = "MyCustomException";
return new ResponseEntity<>(msg ,
HttpStatus.OK);
}
}
I trow a MyCustomException in my Controller but it wasn't handled by handlerMyException() method:
ERROR 1 --- [ajp-nio-8009-exec-372] o.s.b.w.servlet.support.ErrorPageFilter : Forwarding to error page from request [/api/test] due to exception
Then I disable the ErrorPageFilter by:
setRegisterErrorPageFilter(false);
this time no error log occurred, but handlerMyException() still not triggered. Is anyone know this? TIA!

JBoss 7.1.1.Final - EJB Remote Call - java.lang.IllegalStateException: No EJB receiver available for handling

I do have 2 JBoss stanalon instance running. 1 act as Server and another 1 would client.
SERVER:
Remote Interface
package com.xyz.life.service.ejb;
import java.io.Serializable;
import java.rmi.RemoteException;
import javax.ejb.EJB;
import javax.ejb.Remote;
#Remote
public interface QuoteFacade extends Serializable{
public boolean isAlive() throws RemoteException;
}
EJB Impl
package com.xyz.life.common.component.ejb.services;
import java.rmi.RemoteException;
import javax.ejb.Remote;
import javax.ejb.Stateless;
#Stateless(mappedName = "QuoteFacadeEJB")
#Remote(QuoteFacade.class)
public class QuoteFacadeEJB extends CommonSessionBean implements QuoteFacade {
private static final long serialVersionUID = -8788783322280644881L;
#Override
public boolean isAlive() throws RemoteException {
return true;
}
}
server.log
16:40:25,012 INFO [org.jboss.as.ejb3.deployment.processors.EjbJndiBindingsDeploymentUnitProcessor] (MSC service thread 1-4) JNDI bindings for session bean named QuoteFacadeEJB in deployment unit subdeployment "quote.jar" of deployment "quote.ear" are as follows:
java:global/quote/quote.jar/QuoteFacadeEJB!com.xyz.life.service.ejb.QuoteFacade
java:app/quote.jar/QuoteFacadeEJB!com.xyz.life.service.ejb.QuoteFacade
java:module/QuoteFacadeEJB!com.xyz.life.service.ejb.QuoteFacade
java:jboss/exported/quote/quote.jar/QuoteFacadeEJB!com.xyz.life.service.ejb.QuoteFacade
java:global/quote/quote.jar/QuoteFacadeEJB
java:app/quote.jar/QuoteFacadeEJB
java:module/QuoteFacadeEJB
Client
public void testClient() {
try {
Hashtable<String, Object> jndiProps = new Hashtable<String, Object>();
jndiProps.put(Context.URL_PKG_PREFIXES, JNDINames.JBOSS_CLIENT_NAMING_PREFIX);
jndiProps.put("jboss.naming.client.ejb.context", true);
Context ctx = new InitialContext(jndiProps);
String name = "ejb:global/quote/quote.jar/QuoteFacadeEJB!com.ge.life.annuity.service.ejb.QuoteFacade";
/*
"ejb:global/quote/quote.jar/QuoteFacadeEJB!com.ge.life.annuity.service.ejb.QuoteFacade",
"ejb:app/quote.jar/QuoteFacadeEJB!com.ge.life.annuity.service.ejb.QuoteFacade",
"ejb:jboss/exported/quote/quote.jar/QuoteFacadeEJB!com.ge.life.annuity.service.ejb.QuoteFacade"
*/
Object ref = ctx.lookup(name);
QuoteFacade quoteFacade = (QuoteFacade) ref;
LOGGER.debug("isAlive : " + quoteFacade.isAlive());
} catch (Exception e) {
LOGGER.error("Remote Client Exception : ", e);
}
}
No error/log on server side. Client side, it is failing with following error:
java.lang.IllegalStateException: No EJB receiver available for handling [appName:global,modulename:quote,distinctname:quote.jar] combination for invocation context org.jboss.ejb.client.EJBClientInvocationContext#200cae
at org.jboss.ejb.client.EJBClientContext.requireEJBReceiver(EJBClientContext.java:584)
at org.jboss.ejb.client.ReceiverInterceptor.handleInvocation(ReceiverInterceptor.java:119)
at org.jboss.ejb.client.EJBClientInvocationContext.sendRequest(EJBClientInvocationContext.java:181)
at org.jboss.ejb.client.EJBInvocationHandler.doInvoke(EJBInvocationHandler.java:136)
at org.jboss.ejb.client.EJBInvocationHandler.doInvoke(EJBInvocationHandler.java:121)
at org.jboss.ejb.client.EJBInvocationHandler.invoke(EJBInvocationHandler.java:104)
at $Proxy10.isAlive(Unknown Source)
I tried without using Properties file:
private static QuoteFacade connectToStatelessBean(String name) throws NamingException {
Properties jndiProperties = new Properties();
jndiProperties.put(Context.URL_PKG_PREFIXES, "org.jboss.ejb.client.naming");
jndiProperties.put(javax.naming.Context.INITIAL_CONTEXT_FACTORY, "org.jboss.naming.remote.client.InitialContextFactory");
jndiProperties.put(javax.naming.Context.PROVIDER_URL, "remote://localhost:4447");
jndiProperties.put(javax.naming.Context.SECURITY_PRINCIPAL, "admin");
jndiProperties.put(javax.naming.Context.SECURITY_CREDENTIALS, "Pass1234");
final Context context = new InitialContext(jndiProperties);
return (QuoteFacade) context.lookup(name);
}
public static void testLocal() {
String[] JNDINAME1 = {
"ejb:global/quote/quote.jar/QuoteFacadeEJB!com.ge.life.annuity.service.ejb.QuoteFacade",
"ejb:app/quote.jar/QuoteFacadeEJB!com.ge.life.annuity.service.ejb.QuoteFacade",
"ejb:module/QuoteFacadeEJB!com.ge.life.annuity.service.ejb.QuoteFacade",
"ejb:jboss/exported/quote/quote.jar/QuoteFacadeEJB!com.ge.life.annuity.service.ejb.QuoteFacade",
"ejb:global/quote/quote.jar/QuoteFacadeEJB",
"ejb:app/quote.jar/QuoteFacadeEJB",
"ejb:module/QuoteFacadeEJB"
};
for(int i=0;i<JNDINAME1.length;i++){
try {
QuoteFacade test1 = connectToStatelessBean(JNDINAME1[i]);
LOGGER.error("DSLKAJDLAS : " + test1.isAlive());
} catch (Exception e) {
LOGGER.error("DSLKAJDLAS : " , e);
}
}
LOGGER.info("Done - SANSSAN!!!!!!!!");
}
This time, different exception :
14.01.2013 17:40:37.627 [ERROR] - EJBClient - DSLKAJDLAS :
javax.naming.NamingException: JBAS011843: Failed instantiate InitialContextFactory org.jboss.naming.remote.client.InitialContextFactory from classloader ModuleClassLoader for Module "deployment.quote.war:main" from Service Module Loader
at org.jboss.as.naming.InitialContextFactoryBuilder.createInitialContextFactory(InitialContextFactoryBuilder.java:64)
at javax.naming.spi.NamingManager.getInitialContext(NamingManager.java:681)
at javax.naming.InitialContext.getDefaultInitCtx(InitialContext.java:307)
at javax.naming.InitialContext.init(InitialContext.java:242)
at javax.naming.InitialContext.><init>(InitialContext.java:216)
at com.xyz.life.test.EJBClient.connectToStatelessBean(EJBClient.java:208)
at com.xyz.life.test.EJBClient.testLocal(EJBClient.java:225)
at com.xyz.life.test.EJBClient.test(EJBClient.java:172)
at com.xyz.life.common.web.struts.plugin.FrameworkStartupPlugIn.init(FrameworkStartupPlugIn.java:99)
at org.apache.struts.action.ActionServlet.initModulePlugIns(ActionServlet.java:1158)
at org.apache.struts.action.ActionServlet.init(ActionServlet.java:473)
at javax.servlet.GenericServlet.init(GenericServlet.java:242)
at org.apache.catalina.core.StandardWrapper.loadServlet(StandardWrapper.java:1202)
at org.apache.catalina.core.StandardWrapper.load(StandardWrapper.java:1102)
at org.apache.catalina.core.StandardContext.loadOnStartup(StandardContext.java:3655)
at org.apache.catalina.core.StandardContext.start(StandardContext.java:3873)
at org.jboss.as.web.deployment.WebDeploymentService.start(WebDeploymentService.java:90)
at org.jboss.msc.service.ServiceControllerImpl$StartTask.startService(ServiceControllerImpl.java:1811)
at org.jboss.msc.service.ServiceControllerImpl$StartTask.run(ServiceControllerImpl.java:1746)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1110)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:603)
at java.lang.Thread.run(Thread.java:722)
Try removing "global" from name:
String name =
"ejb:quote/quote.jar/QuoteFacadeEJB!com.xyz.life.service.ejb.QuoteFacade"
Also, your package name should be com.xyz.life.service.ejb (as seen on server log) and not com.ge.life.annuity.service.ejb.
Anyway, using remote-naming project for remote EJB invocations is discouraged as explained here.
... . So as you can see, we have managed to optimize certain operations by using the EJB client API for EJB lookup/invocation as against using the remote-naming project. There are other EJB client API implementation details (and probably more might be added) which are superior when it is used for remote EJB invocations in client applications as against remote-naming project which doesn't have the intelligence to carry out such optimizations for EJB invocations. That's why the remote-naming project for remote EJB invocations is considered "deprecated". ...
You can check how to do remote EJB invocations using the EJB client API here.
Found it....
The ones I used for Local machines only. Difference JBoss instances, should change the JNDI lookup name...
like
ejb:quote/quote.jar//QuoteFacadeEJB!com.xyz.life.service.ejb.QuoteFacade

Issue with EJB - Stateful Session Bean and Servlet

I have a servlet code which calls a ejb stateful session bean code as follows,
public class UsesBeansSF extends HttpServlet {
protected void processRequest(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setContentType("text/html;charset=UTF-8");
PrintWriter out = response.getWriter();
try {
// do something
}
finally {}
}
private SessionBeanSFRemote lookupSessionBeanSFRemote() {
try {
Context c = new InitialContext();
return (SessionBeanSFRemote) c.lookup("java:global/MyEJBSF/SessionBeanSF!ejbSF.SessionBeanSFRemote");
} catch (NamingException ne) {
Logger.getLogger(getClass().getName()).log(Level.SEVERE, "exception caught", ne);
throw new RuntimeException(ne);
}
}
}
This code works well without the line between * marks. However, when I am adding SessionBeanSFRemote sessionBeanSF = lookupSessionBeanSFRemote() this line (means calling a Stateful Session Bean), the code is giving error. Actually, I have to call the stateless session bean in order to perform some job. Can anybody help me why it is happening ? Thanks in advance.
Error message is following:
type Exception report message
descriptionThe server encountered an internal error () that prevented it from fulfilling this request.
exception
javax.servlet.ServletException: PWC1392: Error instantiating servlet class websSF.comsSF.UsesBeansSF
root cause
com.sun.enterprise.container.common.spi.util.InjectionException:
Error creating managed object for class websSF.comsSF.UsesBeansSF
root cause
java.lang.reflect.InvocationTargetException
root cause
java.lang.RuntimeException: javax.naming.NamingException:
Lookup failed for 'java:global/MyEJBSF/SessionBeanSF!ejbSF.SessionBeanSFRemote' in SerialContext
[Root exception is javax.naming.NamingException:
ejb ref resolution error for remote business interfaceejbSF.SessionBeanSFRemote [Root exception is java.lang.NullPointerException]]
root cause
javax.naming.NamingException:
Lookup failed for 'java:global/MyEJBSF/SessionBeanSF!ejbSF.SessionBeanSFRemote' in SerialContext
[Root exception is javax.naming.NamingException:
ejb ref resolution error for remote business interfaceejbSF.SessionBeanSFRemote
[Root exception is java.lang.NullPointerException]]
root cause
javax.naming.NamingException: ejb ref resolution error for remote business
interfaceejbSF.SessionBeanSFRemote [Root exception is java.lang.NullPointerException]
root cause
java.lang.NullPointerException
note The full stack traces of the exception and its root causes are available in the GlassFish Server Open Source Edition 3.0.1 logs.
Server: GlassFish Server Open Source Edition 3.0.1
I'm not sure if you have properly set up your Stateful bean. You can try this:
#Stateful(mappedName = "ejb/myStatefulBean")
public class MyStatefulBean implements MyStatefulRemoteInterface {
// Your implementation
}
then you can look it up with:
InitialContext context = new InitialContext();
MyStatefulRemoteInterface myStatefulBean = (MyStatefulRemoteInterface) context.lookup("ejb/myStatefulBean");
Besides, this stateful bean should be saved into each client's session for re-using:
HttpSession clientSession = request.getSession(false);
clientSession.setAttribute("myStatefulBean", myStatefulBean);
In future requests, you can try to get the bean from the client' session first before creating a new one for him.

Resources