i have a problem is:
java.lang.Exception: ServletConfig has not been initialized
I searched for it nearly 2 days but i did not have a solution for me. Every one had said that
super.init(config) must be used. I have tried this, but there is nothing change for me.
My init method;
#Override
public void init(ServletConfig config) throws ServletException {
super.init(config);
AppServiceServlet service = new AppServiceServlet();
try {
service.getir();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
AutoCheckStatus.autoCheckStatus(600000);
}
and my AppServiceServlet;
public List<SswAppServiceDto> getir() throws Exception {
try {
final WebApplicationContext context = WebApplicationContextUtils.getWebApplicationContext(this
.getServletContext());
setiAppServiceBusinessManager((IAppServiceBusinessManager) context.getBean(BEAN_ADI));
List<SswAppService> result = getiAppServiceBusinessManager().getir();
List<SswAppServiceDto> list = DtoConverter.convertSswAppServiceDto(result);
for (int i = 0; i < result.size(); i++) {
AppService appService = new AppService();
appService.setServiceName(result.get(i).getName());
appService.setUid(result.get(i).getServiceUid());
appService.setHost(result.get(i).getHost());
appService.setPort((int) result.get(i).getPort());
SystemConfiguration.appServiceList.put(appService.getUid(), appService);
}
return list;
} catch (RuntimeException e) {
throw new Exception(e.getMessage(), e.getCause());
}
}
The exception is thrown in this line;
final WebApplicationContext context = WebApplicationContextUtils.getWebApplicationContext(this.getServletContext());
in AppServiceServlet and says:
java.lang.Exception: ServletConfig has not been initialized.
Pls help.
This call:
AppServiceServlet service = new AppServiceServlet();
Instantiates a servlet instance via new, which circumvents the normal, container managed creation of a servlet. As such, critical class variables (for example, the servlet config) don't get properly initialized.
Later on, you are making a call to getServletContext, which simply redirects to getServletConfig().getServletContext(), but because the servlet configuration was never completed you get an exception.
Infact, calling new on a servlet the way you are is non-compliant with the specification - servlets are supposed to be maintained by the web app container. The proper way to launch a startup servlet is either via configuration in your web.xml file, or via annotation.
Related
Bank.java
#Stateless
#Local
public class Bank implements IBank {
#EJB
IConfigBean iConfigBean;
#EJB
IDbs iDBS;
#EJB
IPosb iPosb;
#Override
public void doTransaction() {
System.out.println("--Bank Transaction Started--");
try {
Config config1 = getConfig(1);
iConfigBean.create(config1);
iDBS.doDBSTransaction();
Config config3 = getConfig(3);
iConfigBean.create(config3);
iPosb.doPOSBTransaction();
Config config5 = getConfig(5);
iConfigBean.create(config5);
} catch (Exception e) {
e.printStackTrace();
System.out.println("---Bank Exception--");
}
System.out.println("--Bank Transaction End--");
}
#Override
public Config getConfig(int inserttionOrderNo) {
Config config = new Config();
config.setType("EJBTransactionTESTING - " + inserttionOrderNo);
return config;
}
}
DBS.java
#Stateless
#Local
public class DBS implements IDbs {
#EJB
IConfigBean iConfigBean;
#Override
public void doDBSTransaction() {
System.out.println("--DBS Transaction Started--");
try {
Config config2 = getConfig(2);
iConfigBean.create(config2);
} catch (Exception e) {
e.printStackTrace();
System.out.println("--DBS Exception--");
}
System.out.println("--DBS Transaction End--");
}
#Override
public Config getConfig(int inserttionOrderNo) {
Config config = new Config();
config.setType("EJBTransactionTESTING - " + inserttionOrderNo);
return config;
}
}
POSB.java
#Stateless
#Local
public class POSB implements IPosb {
#EJB
IConfigBean iConfigBean;
#Override
public void doPOSBTransaction() {
System.out.println("--POSB Transaction Started--");
try {
Config config4 = getConfig(4);
iConfigBean.create(config4);
if (true) {
//For Test 1
//throw new NullPointerException();
}
} catch (Exception e) {
e.printStackTrace();
System.out.println("--POSB Exception--");
}
if (true) {
//For Test 2
// throw new NullPointerException();
}
System.out.println("--POSB Transaction End--");
}
#Override
public Config getConfig(int inserttionOrderNo) {
Config config = new Config();
config.setType("EJBTransactionTESTING - " + inserttionOrderNo);
return config;
}
}
I am new to Stack Overflow and Its my new question so correct me If I am wrong.
Environment is..
Windows 10
Java 1.8
Eclipse
Tomcat 8.5
EJB3
I have Three stateless bean, Please look at the Sequence Diagram of the Transaction flow.
I purposely making NullPointer Exception at two places during the transaction to know the difference and I have marked with Lightening Bold symbol in sequence diagram.
I am not using any #TransactionAttribute to any methods.
Test 1 - Null Pointer in Inside the try block (Lightening Bold symbol with Green)
When I start the testing, Got Null pointer exception and all the transaction are not marked for roll back and data also got inserted in db.
I can only see Null pointer exception in the console log.
Test 2 - Null Pointer in Outside the try - catch method (Lightening Bold symbol with Red)
When I start the testing, Got Null pointer exception plus EJBTransactionRolledbackException and all the transaction marked for roll back and no data inserted in db.
I can see NullPointer and EJBTransactionRolledback Exception in the console log.
Question here is,
Why EJB transaction is not marked for roll back If I made Null pointer inside try block
Why EJB transaction is roll back happens If I made null pointer outside try block
Thanks in advance.
Keep in mind EJB calls, all the "magic" made by container happens there, including transaction markup. It's possible due to the fact that EJB calls are not direct, but always go through proxy.
You have such calls in your code:
iPosb.doPOSBTransaction();
So, if unchecked exception (NPE for example) is thrown in this method and not caught - it's ultimately caught by container due to EJB proxy wrapping the call above. In this case transaction only could be rolled back.
Adding a call to a method of the same bean in your method (without using #EJB reference), does not change that:
#Override
public void doPOSBTransaction() {
try {
Config config4 = getConfig(4);
iConfigBean.create(config4);
if (true) {
newMethod();
}
} catch (Exception e) {
e.printStackTrace();
System.out.println("--POSB Exception--");
}
if (true) {
newMethod();
}
}
private void newMethod(){
throw new RuntimeException();
}
You can easily check that commit/rollback behaviour is just the same in this case, no matter that a method is added to call stack.
So the important thing you have to remember is that all container tricks work only on #EJB calls. So, for example, it's pointless to place transactional annotation on a private method - it won't be used ever.
Another important point is about checked exceptions. By default these do not cause transaction rollback indeed. But it's still possible to annotate your checked exception like below to make it rollback ongoing transaction:
#ApplicationException(rollback = true)
I want to "globally" catch a Runtime exception, now this sounds silly right but let me explain.
I have created a interceptor that I use on all my ejbs which require authorization to use, this interceptor is called every time a method is called.
See here the code:
#Secure
#Interceptor
public class SecurityInterceptor {
#EJB
private SessionManager sessionManager;
#AroundInvoke
private Object securityCheck(InvocationContext ctx) throws Exception {
System.out.println("hello");
List<UserGroup> allowedRoles = (List<UserGroup>) ctx.getContextData().get("rolesAllowed");
sessionManager.isAuthorized(allowedRoles);
return ctx.proceed();
}
}
Now I don't want in my Named Bean to surround the body of every method that uses one of these secured beans with a try and catch block, like this:
public List<Contracts> getContracts() {
List<Contracts> contracts = new ArrayList<>();
try {
contracts = contractEntityManager.getAll();
} catch (EJBTransactionRolledbackException e) {
Throwable throwable = ExceptionUtils.getRootCause(e);
if (throwable instanceof NotAuthenticatedException) {
System.out.println("Not Authenticated");
}
else if (throwable instanceof UnAuthorizedException) {
System.out.println("Not Authorized");
}
}
return contracts;
}
So is there some way to globally catch a runtime exception and the redirect the user to the login page if he is unauthenticated and to a error page when he is unauthorized.
Maybe my design is just generally bad and I would need to complety rethink this idea.
Please let me know.
Thank you
So, in the end, it is the in the web tier that you want to catch the exceptions. This is easy:
If you are only on servlets, specify the error-page element in web.xml for each exception you wish to handle, e.g. as follows:
<error-page>
<exception-type>fully.quallified.NotAuthenticatedException</exception-type>
<location>/where/to/redirect/eg/login</location>
</error-page>
You declare the exception you want to handle globally and the URL you want to handle it, it may be a servlet, a JSP or any other resource.
JAX-RS offers a similar mechanism with the javax.ws.rs.ext.ExceptionMapper:
#Provider
public class NotAuthenticatedExceptionMapper implements ExceptionMapper<NotAuthenticatedException> {
...
}
When I shut down Tomcat, I observe a correct shutdown and cleanup of the Spring WebApplicationContext. However, when I redeploy my Spring-based WAR (by copying the new WAR to webapps), normal shutdown does not occur. This is a problem for me due to all the ensuing resource leaks:
org.apache.catalina.loader.WebappClassLoader clearReferencesThreads
SEVERE: The web application [] appears to have started a thread named [hz.hazelcast-swipe-instance.scheduled] but has failed to stop it. This is very likely to create a memory leak.
org.apache.catalina.loader.WebappClassLoader clearReferencesThreads
SEVERE: The web application [] appears to have started a thread named [hz.hazelcast-swipe-instance.operation.thread-0] but has failed to stop it. This is very likely to create a memory leak.
... and many more. I am using XML-less configuration, this is my WebApplicationInitializer:
public class WebApplicationInitializer extends AbstractAnnotationConfigDispatcherServletInitializer
{
#Override protected Class<?>[] getRootConfigClasses() {
return new Class[] { WebSecurityConfig.class, WebMvcConfig.class };
}
#Override protected Class<?>[] getServletConfigClasses() { return null; }
#Override protected String[] getServletMappings() { return new String[] { "/" }; }
#Override public void onStartup(ServletContext ctx) throws ServletException {
ctx.setInitParameter("spring.profiles.active", "production");
super.onStartup(ctx);
}
}
There is no configuration specific to controlling the behavior upon servlet context reload, and I assume this should have worked out of the box.
Is there a way to make the WebApplicationContext close properly before continuing the servlet context reloading procedure?
I am on Spring 4.0.5, Tomcat 7.0.54, Hazelcast 3.2.1, Hibernate 4.3.4.Final.
Update
I have added a Spring application listener for the ContextClosedEvent and printed the stack trace of its invocation:
at org.springframework.context.support.AbstractApplicationContext.publishEvent(AbstractApplicationContext.java:333) [spring-context-4.0.6.RELEASE.jar:4.0.6.RELEASE]
at org.springframework.context.support.AbstractApplicationContext.publishEvent(AbstractApplicationContext.java:335) [spring-context-4.0.6.RELEASE.jar:4.0.6.RELEASE]
at org.springframework.context.support.AbstractApplicationContext.doClose(AbstractApplicationContext.java:880) [spring-context-4.0.6.RELEASE.jar:4.0.6.RELEASE]
at org.springframework.context.support.AbstractApplicationContext.close(AbstractApplicationContext.java:841) [spring-context-4.0.6.RELEASE.jar:4.0.6.RELEASE]
at org.springframework.web.servlet.FrameworkServlet.destroy(FrameworkServlet.java:819) [spring-webmvc-4.0.6.RELEASE.jar:4.0.6.RELEASE]
at org.apache.catalina.core.StandardWrapper.unload(StandardWrapper.java:1486) [catalina.jar:7.0.54]
at org.apache.catalina.core.StandardWrapper.stopInternal(StandardWrapper.java:1847) [catalina.jar:7.0.54]
at org.apache.catalina.util.LifecycleBase.stop(LifecycleBase.java:232) [catalina.jar:7.0.54]
at org.apache.catalina.core.StandardContext.stopInternal(StandardContext.java:5647) [catalina.jar:7.0.54]
at org.apache.catalina.util.LifecycleBase.stop(LifecycleBase.java:232) [catalina.jar:7.0.54]
at org.apache.catalina.core.ContainerBase$StopChild.call(ContainerBase.java:1575) [catalina.jar:7.0.54]
at org.apache.catalina.core.ContainerBase$StopChild.call(ContainerBase.java:1564) [catalina.jar:7.0.54]
This indicates that the Spring shutdown occurs in its Servlet#destroy method. This is the relevant snippet from AbstractApplicationContext#close():
if (logger.isInfoEnabled()) {
logger.info("Closing " + this);
}
LiveBeansView.unregisterApplicationContext(this);
try {
// Publish shutdown event.
publishEvent(new ContextClosedEvent(this));
}
catch (Throwable ex) {
logger.warn("Exception thrown from ApplicationListener handling ContextClosedEvent", ex);
}
// Stop all Lifecycle beans, to avoid delays during individual destruction.
try {
getLifecycleProcessor().onClose();
}
catch (Throwable ex) {
logger.warn("Exception thrown from LifecycleProcessor on context close", ex);
}
// Destroy all cached singletons in the context's BeanFactory.
destroyBeans();
// Close the state of this context itself.
closeBeanFactory();
// Let subclasses do some final clean-up if they wish...
onClose();
synchronized (this.activeMonitor) {
this.active = false;
}
I see the log entry from the start of this snippet, and I get my ContextClosedEvent. I also see an entry DefaultLifecycleProcessor - Stopping beans in phase 2147483647, which probably comes from the getLifecycleProcessor.onClose() line. It seems that some error occurs downstream from that. Some exception may be swallowed.
Update 2
As requested, this is how I configure Hazelcast:
#Bean(destroyMethod="shutdown") public HazelcastInstance hazelcast() {
final Config c = hzConfig();
final JoinConfig join = c.getNetworkConfig().getJoin();
join.getMulticastConfig().setEnabled(false);
join.getTcpIpConfig().setEnabled(true);
return getOrCreateHazelcastInstance(c);
}
hzConfig() is a method where instance name, group name and password, map names, and map indices are configured, so I don't think it is of interest here.
And this is my Hibernate SessionFactory config:
#Bean
public LocalSessionFactoryBean sessionFactory() {
final LocalSessionFactoryBean b = new LocalSessionFactoryBean();
b.setDataSource(dataSource);
b.setHibernateProperties(props(
"hibernate.connection.release_mode", "on_close",
"hibernate.id.new_generator_mappings", "true",
"hibernate.hbm2ddl.auto", "update",
"hibernate.order_inserts", "true",
"hibernate.order_updates", "true",
"hibernate.max_fetch_depth", "0",
"hibernate.jdbc.fetch_size", "200",
"hibernate.jdbc.batch_size", "50",
"hibernate.jdbc.batch_versioned_data", "true",
"hibernate.jdbc.use_streams_for_binary", "true",
"hibernate.use_sql_comments", "true"
));
return b;
}
At some point, you mentioned that there was a NoClassDefFoundError for Logback. You got this fixed by removing this dependency, but then the problem moved to a another class - one of Spring's own classes.
This can mean that either one of the libraries you have does something buggy with class loaders or maybe Tomcat needs instructions not to keep locks on some resources. See here more about Tomcat resources being locked and the <Context> setting to try: in your Tomcat's conf/context.xml place a antiResourceLocking="true" to the element.
Have you tried upping unloadDelay (defaults to 2000ms) for Tomcat contexts? See http://tomcat.apache.org/tomcat-7.0-doc/config/context.html
UPDATE: I see that you are having issues with logback as well, it might be worth the shot to try and register this listener as well:
class LogbackShutdownListener implements ServletContextListener {
#Override
public void contextDestroyed(ServletContextEvent event) {
LoggerContext loggerContext = (LoggerContext)LoggerFactory.getILoggerFactory();
System.out.println("Shutting down Logback context '" + loggerContext.getName() + "' for " + contextRootFor(event));
loggerContext.stop();
}
#Override
public void contextInitialized(ServletContextEvent event) {
System.out.println("Logback context shutdown listener registered for " + contextRootFor(event));
}
private String contextRootFor(ServletContextEvent event) {
return event.getServletContext().getContextPath();
}
}
Be sure to declare this listener before the spring context loader listener so that it is invoked after the context listener upon shutdown.
UPDATE 2: Also it might be worth the try to register another bean to handle closing of the Hazelcast stuff manually (be sure to also remove destroyMethod from the hazelcast bean):
#Component
class HazelcastDestructor {
#Autowired
private HazelcastInstance instance;
#PreDestroy
public void shutdown() {
try {
instance.shutdown();
} catch (Exception e) {
System.out.println("Hazelcast failed to shutdown(): " + e);
throw e;
}
}
}
UPDATE 3: Just out of curiosity, have you tried parallel deployment: http://www.javacodegeeks.com/2011/06/zero-downtime-deployment-and-rollback.html. It might behave differently than reloading the very same context. At the very least you should be able to undeploy the old version lazily and see if that makes a difference.
There is a similar issue on the dangling threads while container restarting here.
Of all the answers, one particular answer of interest was by Howard - which shows the way these threads are cleared.
There is some good discussion and reasoning as to how this can terminate the threads here.
Now implement ServletContextListener and take care of these threads in the contextDestroyed() method as:
public class YourListener implements ServletContextListener{
....
#Override
public void contextDestroyed(ServletContextEvent event) {
//Call the immolate method here
}
}
Register this listener in WebApplicationInitilizer as:
ctx.addListener(new YourListener());
So when server is restarted - contextDestroyed method is called and this takes care of all these threads.
From Web App development point of view, ServletContainer can only notify the before started and before end process of app.
It is using ServletContextListener.
Config ServletContextListener in web.xml
<listener>
<listener-class>com.var.YourListener</listener-class>
</listener>
YourListener.java
public class YourListener implements ServletContextListener {
public void contextInitialized(ServletContextEvent sce) {
//initialization process
}
public void contextDestroyed(ServletContextEvent sce) {
//destory process
}
}
Update -XML Less
Programmatically
#Override
public void onStartup(ServletContext ctx) throws ServletException {
ctx.addListener(new YourContextListener());
ctx.setInitParameter("spring.profiles.active", "production");
super.onStartup(ctx);
}
Annotation
#WebListener / #WebServletContextListener
public class YourContextListener implements ServletContextListener {
public void contextInitialized(ServletContextEvent servletContextEvent) {
}
public void contextDestroyed(ServletContextEvent servletContextEvent) {
}
}
Update- ShoutDown Hook In Spring
I never use it before my app development, we can register shoutdownhook event into AbstractApplicationContext of Spring.
I am not sure it will be ok or not for you.
AbstractApplicationContext context = ...
context.registerShutdownHook();
Reference 1 Reference 2
In Spring through the ApplicationContext class I can utilise IoC features and get a reference to a bean as follows
public class Driver {
public static void main(String args[])
{
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("/spring-config.xml");
MyClass myClass = (MyClass)applicationContext.getBean("myClass");
}
I would like to be able to do the same with Java EE, but I don't seem to be able to outside of an application server.
I'm trying the following
public class Driver {
public static void main(String args[])
{
InitialContext ic;
try {
ic = new InitialContext();
// JNDI lookup
MyClass myClass = (MyClass)ic.lookup("java:module/MyClass");
} catch (NamingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (SecurityException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
So far with this approach I get a javax.naming.NoInitialContextException.
My question is how can load up IoC features in a standalone application using Java EE?
EDIT Thanks for the help guys...I went with the OpenWebBeans CDI implementation... Thanks for the help.
Currently you are working with JNDI, not an IoC.
If you want JNDI worked in standalone application to locate remote data google for "jndi client".
If you want to use IoC in your Java EE application - check CDI
If you need to get JNDI resource outside web-container or application server, then before lookup you need to bind resource. But before binding you need to implement and register javax.naming.spi.InitialContextFactory implementation.
In the easiest way I would suggest to keep all bindings in the global java.util.concurrent.ConcurrentHashMap.
So it should look like the following (please keep in mind that this is easiest solution, and it might not work properly in some cases, but it satisfies your particular request):
public class Driver {
//static initializtion
static {
//registering you custom InitialContextFactory
//note, that you can register it in some other way, check http://docs.oracle.com/javase/jndi/tutorial/beyond/env/source.html
System.setProperty("java.naming.factory.initial", SimpleInitialContextFactory.class.getName());
bindMyClass();
}
private static void bindMyClass(){
try {
InitialContext context = new InitialContext();
context.bind("java:module/MyClass", new MyClass());
} catch (NamingException ignored) {}
}
public static void main(String args[]) throws Exception {
InitialContext ic = new InitialContext();
// JNDI lookup
MyClass myClass = (MyClass)ic.lookup("java:module/MyClass");//should find it
}
}
class SimpleInitialContextFactory implements InitialContextFactory {
#Override
public Context getInitialContext(Hashtable<?, ?> environment) throws NamingException {
return new MapBasedContext(environment);
}
}
public class MapBasedContext implements Context {
//actual holder of context
private static Map values = new ConcurrentHashMap();
public MapBasedContext() {
}
public MapBasedContext(Hashtable<?, ?> environment) {
values.putAll(environment);
}
#Override
public void bind(String name, Object obj) throws NamingException {
values.put(name, obj);
}
#Override
public Object lookup(String name) throws NamingException {
return values.get(name); //you may throw an exception in case if name is absent
}
//TODO everything else should be implemented, but actual methods bodies aren't required
}
CDI is the spring "equivalent" in java EE 6 (in fact it is not equivalent cause it covers only Context and DI features, the others one are covered by other JSR implementation like EJB or JPA but if your problem is only to use DI then it will fit perfectly. You won't be able however to use others spring / Java EE features like Container managed transaction for example)
If you want to run it in a standalone application, go on Jboss WELD CDI implementation.
Personally i think that's it's farly better than spring for Context and DI management, but here's not the place to troll
I'm embedding Jetty in a similar manner as described here. When the RequestLogHandler can't open the specified logfile, it throws an exception which is unfortunately caught by org.eclipse.jetty.server.Server and swallowed (but logged first, at least). This means that there's no obvious way for me to tell if the log handler was started correctly.
Is there a way that I'm missing to detect when a handler couldn't start?
This idea is based on the implementation of WebAppContext where you can use WebAppContext.getUnavailableException() to determine whether the context was initialized successfully.
Simply replace the default implementation of Server and Context with your own:
public static class MyContext extends Context {
private Exception _exception;
#Override
protected void doStart() throws Exception {
try {
super.doStart();
} catch (final Exception e) {
_exception = e;
}
}
#Override
protected void doStop() throws Exception {
try {
super.doStop();
} finally {
_exception = null;
}
}
public Exception getException() {
return _exception;
}
}
public static class MyServer extends Server implements InitializingBean {
public void afterPropertiesSet() throws Exception {
start();
for (final Handler h : getHandlers()) {
if (h instanceof MyContext) {
final MyContext c = (MyContext) h;
if (c.getException() != null) {
throw new RuntimeException("failed to init context " + c.getDisplayName(),
c.getException());
}
}
}
}
}
In your beans.xml, simply replace org.mortbay.jetty.Server (and remove init-method="start") and org.mortbay.jetty.servlet.Context with your own implementations.
This code is for Jetty 6 though (as is the example you linked to), as that's what I have around. I didn't test it though, but it's pretty much the same as we are successfully using in conjunction with WebAppContext. In order to extend this to RequestLogHandler, you could either do the same for just any handler you are using or create a decorator to wrap any handler. You may want to look at org.mortbay.jetty.handler.HandlerWrapper for this purpose.
How about modifying the jetty code? You could add some simple println statements in strategic places in the RequestLogHandler which would indicate to you whether or not the handler was started.