Scope conflicts until batch job finished? - cdi

Tech stack:
JBeret (core, se) 1.3.0.Final
Hibernate Search (orm, jsr352-core, jsr352-jberet) 5.10.4.Final
Weld (servlet-core, se-core) 3.0.5.Final
If I trigger
BatchRuntime.getJobOperator().start(
MassIndexingJob.NAME,
MassIndexingJob.parameters().forEntity(getDomainObjectClass()).build()
);
then I had the situation that a can't access any CDI component outside of the batch job that are RequestScoped or SessionScoped, until the batch job is finished.
How I can fix this problem?
Part of the stacktrace
Caused by: org.jboss.weld.contexts.ContextNotActiveException: WELD-001303: No active contexts for scope type javax.enterprise.context.RequestScoped
at org.jboss.weld.manager.BeanManagerImpl.getContext(BeanManagerImpl.java:647) ~[weld-core-impl-3.0.5.Final.jar:3.0.5.Final]
at org.jboss.weld.bean.ContextualInstanceStrategy$DefaultContextualInstanceStrategy.getIfExists(ContextualInstanceStrategy.java:89) ~[weld-core-impl-3.0.5.Final.jar:3.0.5.Final]
at org.jboss.weld.bean.ContextualInstanceStrategy$CachingContextualInstanceStrategy.getIfExists(ContextualInstanceStrategy.java:164) ~[weld-core-impl-3.0.5.Final.jar:3.0.5.Final]
at org.jboss.weld.bean.ContextualInstance.getIfExists(ContextualInstance.java:63) ~[weld-core-impl-3.0.5.Final.jar:3.0.5.Final]
at org.jboss.weld.bean.proxy.ContextBeanInstance.getInstance(ContextBeanInstance.java:87) ~[weld-core-impl-3.0.5.Final.jar:3.0.5.Final]
at org.jboss.weld.bean.proxy.ProxyMethodHandler.getInstance(ProxyMethodHandler.java:131) ~[weld-core-impl-3.0.5.Final.jar:3.0.5.Final]
at foo.bar.Baz$Proxy$_$$_WeldClientProxy.getFoo(Unknown Source) ~[classes/:na]
Annotated #ActivateRequestContext produce this stacktrace on startup/deployment
Caused by: org.jboss.weld.exceptions.WeldException: WELD-001524: Unable to load proxy class for bean Managed Bean [class foo.bar.Bean] with qualifiers [#Any #Default] with class class foo.bar.Bean using classloader ParallelWebappClassLoader
context: foobar
delegate: false
----------> Parent Classloader:
java.net.URLClassLoader#58a9760d
at org.jboss.weld.bean.proxy.ProxyFactory.getProxyClass(ProxyFactory.java:370)
at org.jboss.weld.injection.producer.SubclassedComponentInstantiator.createEnhancedSubclass(SubclassedComponentInstantiator.java:113)
at org.jboss.weld.injection.producer.SubclassedComponentInstantiator.initEnhancedSubclass(SubclassedComponentInstantiator.java:86)
at org.jboss.weld.injection.producer.SubclassedComponentInstantiator.<init>(SubclassedComponentInstantiator.java:79)
at org.jboss.weld.injection.producer.SubclassedComponentInstantiator.forInterceptedDecoratedBean(SubclassedComponentInstantiator.java:63)
at org.jboss.weld.injection.producer.BeanInjectionTarget.initializeAfterBeanDiscovery(BeanInjectionTarget.java:121)
at org.jboss.weld.injection.producer.InjectionTargetInitializationContext.initialize(InjectionTargetInitializationContext.java:42)
at org.jboss.weld.injection.producer.InjectionTargetService.initialize(InjectionTargetService.java:63)
at org.jboss.weld.bootstrap.WeldStartup.deployBeans(WeldStartup.java:475)
at org.jboss.weld.bootstrap.WeldBootstrap.deployBeans(WeldBootstrap.java:86)
at org.jboss.weld.environment.servlet.WeldServletLifecycle.initialize(WeldServletLifecycle.java:236)
at org.jboss.weld.environment.servlet.EnhancedListener.onStartup(EnhancedListener.java:62)
at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5245)
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150)
... 42 more
Caused by: org.jboss.weld.exceptions.WeldException: Cannot load variable at 0. Local Variables: Local Variables: []
at org.jboss.weld.bean.proxy.InterceptedSubclassFactory.addMethodsFromClass(InterceptedSubclassFactory.java:262)
at org.jboss.weld.bean.proxy.InterceptedSubclassFactory.addMethods(InterceptedSubclassFactory.java:136)
at org.jboss.weld.bean.proxy.ProxyFactory.createProxyClass(ProxyFactory.java:449)
at org.jboss.weld.bean.proxy.ProxyFactory.getProxyClass(ProxyFactory.java:362)
... 55 more
Caused by: org.jboss.classfilewriter.InvalidBytecodeException: Cannot load variable at 0. Local Variables: Local Variables: []
at org.jboss.classfilewriter.code.CodeAttribute.aload(CodeAttribute.java:196)
at org.jboss.weld.bean.proxy.RunWithinInterceptionDecorationContextGenerator.startIfNotOnTop(RunWithinInterceptionDecorationContextGenerator.java:71)
at org.jboss.weld.bean.proxy.RunWithinInterceptionDecorationContextGenerator.runStartIfNotOnTop(RunWithinInterceptionDecorationContextGenerator.java:148)
at org.jboss.weld.bean.proxy.InterceptedSubclassFactory.addMethodsFromClass(InterceptedSubclassFactory.java:200)
... 58 more

I do not know what exactly JBeret does, but Weld SE out of the box does not activate request context (or session context) which in turn leads to the exception you are seeing. The reason is that in SE there are no HTTP requests (or sessions) hence Weld simply does not know when to activate it.
Although "request" can be interpreted differently and can be valuable addition even in SE - that's why there are supported ways to activate request context, for instance via interceptor. I suppose this is something JBeret does for you and that's why the beans "work" there.
Therefore in order to be able to use your request scoped beans in SE application, you will need to take extra steps. Note however that the context can be different from that of JBeret batch job (you won't see the same beans with the exact same state) as I expect JBeret to offload the work to another thread.

Related

Some problems with hibernate after creating an entity

I'm using the last version of the generator-jhipster.
I have made a microservice-application, build it, it's a success.
Now I'm creating an entity and when I run it, I get this stack trace:
java.lang.IllegalStateException: Failed to load ApplicationContext
at org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContext(DefaultCacheAwareContextLoaderDelegate.java:124)
at org.springframework.test.context.support.DefaultTestContext.getApplicationContext(DefaultTestContext.java:83)
at org.springframework.test.context.web.ServletTestExecutionListener.setUpRequestContextIfNecessary(ServletTestExecutionListener.java:189)
at org.springframework.test.context.web.ServletTestExecutionListener.prepareTestInstance(ServletTestExecutionListener.java:131)
at org.springframework.test.context.TestContextManager.prepareTestInstance(TestContextManager.java:230)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.createTest(SpringJUnit4ClassRunner.java:228)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner$1.runReflectiveCall(SpringJUnit4ClassRunner.java:287)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.methodBlock(SpringJUnit4ClassRunner.java:289)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:247)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:94)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61)
at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:70)
at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:191)
at org.apache.maven.surefire.junit4.JUnit4Provider.execute(JUnit4Provider.java:283)
at org.apache.maven.surefire.junit4.JUnit4Provider.executeWithRerun(JUnit4Provider.java:173)
at org.apache.maven.surefire.junit4.JUnit4Provider.executeTestSet(JUnit4Provider.java:153)
at org.apache.maven.surefire.junit4.JUnit4Provider.invoke(JUnit4Provider.java:128)
at org.apache.maven.surefire.booter.ForkedBooter.invokeProviderInSameClassLoader(ForkedBooter.java:203)
at org.apache.maven.surefire.booter.ForkedBooter.runSuitesInProcess(ForkedBooter.java:155)
at org.apache.maven.surefire.booter.ForkedBooter.main(ForkedBooter.java:103)
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'entityManagerFactory' defined in class path resource [org/springframework/boot/autoconfigure/orm/jpa/HibernateJpaAutoConfiguration.class]: Invocation of init method failed; nested exception is javax.persistence.PersistenceException: [PersistenceUnit: default] Unable to build Hibernate SessionFactory
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1583)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:553)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:482)
at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:306)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:302)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:197)
at org.springframework.context.support.AbstractApplicationContext.getBean(AbstractApplicationContext.java:1081)
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:856)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:542)
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:761)
at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:371)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:315)
at org.springframework.boot.test.context.SpringBootContextLoader.loadContext(SpringBootContextLoader.java:111)
at org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContextInternal(DefaultCacheAwareContextLoaderDelegate.java:98)
at org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContext(DefaultCacheAwareContextLoaderDelegate.java:116)
... 26 common frames omitted
Caused by: javax.persistence.PersistenceException: [PersistenceUnit: default] Unable to build Hibernate SessionFactory
at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.persistenceException(EntityManagerFactoryBuilderImpl.java:955)
at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.build(EntityManagerFactoryBuilderImpl.java:880)
at org.springframework.orm.jpa.vendor.SpringHibernateJpaPersistenceProvider.createContainerEntityManagerFactory(SpringHibernateJpaPersistenceProvider.java:60)
at org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean.createNativeEntityManagerFactory(LocalContainerEntityManagerFactoryBean.java:353)
at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.buildNativeEntityManagerFactory(AbstractEntityManagerFactoryBean.java:373)
at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.afterPropertiesSet(AbstractEntityManagerFactoryBean.java:362)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1642)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1579)
... 41 common frames omitted
Caused by: org.hibernate.tool.schema.spi.SchemaManagementException: Schema-validation: missing sequence [hibernate_sequence]
at org.hibernate.tool.schema.internal.AbstractSchemaValidator.validateSequence(AbstractSchemaValidator.java:184)
at org.hibernate.tool.schema.internal.AbstractSchemaValidator.performValidation(AbstractSchemaValidator.java:100)
at org.hibernate.tool.schema.internal.AbstractSchemaValidator.doValidation(AbstractSchemaValidator.java:68)
at org.hibernate.tool.schema.spi.SchemaManagementToolCoordinator.performDatabaseAction(SchemaManagementToolCoordinator.java:185)
at org.hibernate.tool.schema.spi.SchemaManagementToolCoordinator.process(SchemaManagementToolCoordinator.java:66)
at org.hibernate.internal.SessionFactoryImpl.<init>(SessionFactoryImpl.java:309)
at org.hibernate.boot.internal.SessionFactoryBuilderImpl.build(SessionFactoryBuilderImpl.java:445)
at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.build(EntityManagerFactoryBuilderImpl.java:877)
... 47 common frames omitted
I didn't modify anything, did I do something wrong ?
I had the same issue and my solution may or may not apply to your case. In my case, a previous version of JHipster had generated the hibernate_sequence only for some database types, not including h2 used for tests.
Check your 00000000000000_initial_schema.xml liquibase file, it should contain the instructions for creating the hibernate_sequence sequence, for instance:
<changeSet id="00000000000000" author="jhipster" dbms="postgresql,oracle">
<createSequence sequenceName="hibernate_sequence" startValue="1000" incrementBy="1"/>
</changeSet>
This did not include h2, so the sequence was not generated during testing and thus Hibernate complained.
I removed the dbms="postgresql,oracle" part and then it worked.
your application is failing to load ApplicationContext. Check your folder where it is configured
#ContextConfiguration (locations = "classpath*:/spring/applicationContext*.xml")
this will load all of your application context xml file.
According to stack trace,
Your test class with SpringJUnit4ClassRunner needs a spring context and your spring configuration for this test class needs a bean that's name entityManagerFactory
You must add this bean to your test config(HibernateJpaAutoConfiguration)
For ex:
in Java Config:
#Bean
public EntityManagerFactory entityManagerFactory(){
return new EntityManagerFactory(...){
....
}
}
or autowired:
#Autowire
private EntityManagerFactory entityManagerFactory;

CDI - ContextNotActiveException - WebBeans context with scope type annotation #RequestScoped does not exist within current thread

Environment : WAS 8.0.0.10
CDI : 1.0 (Implementation OpenWebBeans)
Use Case: Server is executing the Java class asynchronously via TimerManager. I am trying to inject the cdi bean with Request scope into the class but when any method is called on the injection, below is the stack trace i am getting. If i use the Applicationscope instead of RequestScope in the injection, Code works fine.
Upon investigating the issue, i found that Request and Session context will not be active for the threads initiallized asynchronously by the container. Is there some way i can initialize the request and session context?
Error :
javax.enterprise.context.ContextNotActiveException: WebBeans context with scope type annotation #RequestScoped does not exist within current thread**
at org.apache.webbeans.container.BeanManagerImpl.getContext(BeanManagerImpl.java:358)
at org.apache.webbeans.intercept.NormalScopedBeanInterceptorHandler.getContextualInstance(NormalScopedBeanInterceptorHandler.java:124)
at org.apache.webbeans.intercept.NormalScopedBeanInterceptorHandler.invoke(NormalScopedBeanInterceptorHandler.java:95)
at com.ford.it.processcontrol.TestJob3_$$_javassist_22.executeJobCB(TestJob3_$$_javassist_22.java)
I'm assuming you already have this, or something alike somewhere:
CdiContainer cdiContainer = CdiContainerLoader.getCdiContainer();
cdiContainer.boot();
ContextControl contextControl = cdiContainer.getContextControl();
Then, somehow you have access to the ContextControl instance. Then you can start the context wherever you need it, just remember to stop it when it's no longer needed
try{
//start
contextControl.startContext(RequestScoped.class);
// do stuff
}catch(Exception e){}
finally{
//stop
contextControl.stopContext(RequestScoped.class);
}
This is working for me in some asynced classes.
Hope it helps.
regards!

Bootstrap Javafx 2.0 with Weld

I am trying to bootstrap a small javafx application using Weld-SE. I was able to run the application if I remove the #Inject annotation on the Menubar and instantiate it manually.
But the moment I add #Inject, the application throws exception. Listed below are the injection point and the Producer method. This is all the configuration I did, am I missing something ?
Injection Point
#Inject MenuBar menuBar
Class with producer method
public class ComponentProducer {
#Produces
public MenuBar createMenuBar(){
return new MenuBar();
}
}
Exception
491 [JavaFX Application Thread] INFO org.jboss.weld.Bootstrap - WELD-000101 Transactional services not available. Injection of #Inject UserTransaction not available. Transactional observers will be invoked synchronously.
8868 [JavaFX Application Thread] WARN org.jboss.interceptor.model.InterceptionTypeRegistry - Class 'javax.ejb.PostActivate' not found, interception based on it is not enabled
8868 [JavaFX Application Thread] WARN org.jboss.interceptor.model.InterceptionTypeRegistry - Class 'javax.ejb.PrePassivate' not found, interception based on it is not enabled
Exception in Application start method
Exception in thread "main" java.lang.RuntimeException: Exception in Application start method
at com.sun.javafx.application.LauncherImpl.launchApplication1(LauncherImpl.java:399)
at com.sun.javafx.application.LauncherImpl.access$000(LauncherImpl.java:47)
at com.sun.javafx.application.LauncherImpl$1.run(LauncherImpl.java:115)
at java.lang.Thread.run(Thread.java:722)
Caused by: java.lang.NullPointerException
at net.sourceforge.squirrel_sql.client.MainScene.<init>(MainScene.java:26)
at net.sourceforge.squirrel_sql.client.FXApplication.startup(FXApplication.java:176)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:601)
at org.jboss.weld.util.reflection.SecureReflections$13.work(SecureReflections.java:304)
at org.jboss.weld.util.reflection.SecureReflectionAccess.run(SecureReflectionAccess.java:54)
at org.jboss.weld.util.reflection.SecureReflectionAccess.runAsInvocation(SecureReflectionAccess.java:163)
at org.jboss.weld.util.reflection.SecureReflections.invoke(SecureReflections.java:298)
at org.jboss.weld.introspector.jlr.WeldMethodImpl.invokeOnInstance(WeldMethodImpl.java:200)
at org.jboss.weld.introspector.ForwardingWeldMethod.invokeOnInstance(ForwardingWeldMethod.java:59)
at org.jboss.weld.injection.MethodInjectionPoint.invokeOnInstanceWithSpecialValue(MethodInjectionPoint.java:194)
at org.jboss.weld.event.ObserverMethodImpl.sendEvent(ObserverMethodImpl.java:241)
at org.jboss.weld.event.ObserverMethodImpl.notify(ObserverMethodImpl.java:216)
at org.jboss.weld.manager.BeanManagerImpl.notifyObservers(BeanManagerImpl.java:654)
at org.jboss.weld.manager.BeanManagerImpl.fireEvent(BeanManagerImpl.java:647)
at org.jboss.weld.manager.BeanManagerImpl.fireEvent(BeanManagerImpl.java:641)
at org.jboss.weld.event.EventImpl.fire(EventImpl.java:93)
at net.sourceforge.squirrel_sql.client.Main.start(Main.java:180)
at com.sun.javafx.application.LauncherImpl$5.run(LauncherImpl.java:315)
at com.sun.javafx.application.PlatformImpl$4.run(PlatformImpl.java:174)
at com.sun.javafx.application.PlatformImpl$3.run(PlatformImpl.java:141)
at com.sun.glass.ui.gtk.GtkApplication._runLoop(Native Method)
at com.sun.glass.ui.gtk.GtkApplication$2$1.run(GtkApplication.java:79)
... 1 more
ShaggyInjun, you refer to the Initializable interface which indicates you were trying to integrate with the FXMLLoader. All of the information below assumes you are using FXML for your interface definition and only discusses issues around injecting values into FXML controllers.
The FXMLLoader has the concept of a controller factory, which you should use to integrate the controller instantiation with your dependency injection system. There is a brief discussion of controller factories in Oracle's Mastering FXML Tutorial. Andy demonstrates definition of such a factory for Guice in his blog and there is a comprehensive integration of Guice in FXML on github.
For Weld you will need to implement a similar controller factory callback mechanism to realize the dependency injection functionality which Weld provides. The article by Matthieu Brouillard that you linked in a comment FXML & JavaFX—Fueled by CDI & JBoss Weld would seem to provide all of the information you need to both initialize Weld and interface Weld into the FXMLLoader controller factory mechanism. Specifically, the following code is the Weld equivalent of Andy Till's FXML based injection mechanism:
public class FXMLLoaderProducer {
#Inject Instance<Object> instance;
#Produces public FXMLLoader createLoader() {
FXMLLoader loader = new FXMLLoader();
loader.setControllerFactory(new Callback<Class<?>, Object>() {
#Override public Object call(Class<?> param) {
return instance.select(param).get();
}
});
return loader;
}
}
Even when an FXMLoader controller factory is used, I believe it is the FXMLLoader that is instantiating the controller. So in those cases, you should not make of annotations like #PostConstruct because they only apply when the dependency injection system is maintaining the lifecycle of the object - and that is not the case if the FXMLLoader creates the controller.
There is one other alternative, and that it is to explicitly set the controller to be used by the FXMLLoader using setController. This would allow you to have your dependency injection system instantiate (and inject into) controllers using whatever means it wishes and then you could subsequently pass the instantiated controller to your FXMLLoader. In such cases anotations like #PostConstruct should work as the dependency injection system is now maintaining the objects lifecycle (and #PostConstruct would be invoked by the dependency injection system after the Controller has been created and before you pass the Controller through to the FXMLLoader).
I'll post Andy's Guice based solution here as it is a small and simple example of how similar injection is accomplished in Guice (in case his blog goes offline):
class GuiceControllerFactory implements Callback<Class<?>, Object> {
private final Injector injector;
public GuiceControllerFactory(Injector anInjector) {
injector = anInjector;
}
#Override public Object call(Class<?> aClass) {
return injector.getInstance(aClass);
}
}
Is it because you are trying to use menuBar in the constructor or initialiser block?
If so, try using Initializable and using them in initialize.
EJB documentation states that the method annotated with #PostConstruct will be called after the injections are done, and that this is the method to expect variable injections.
#PostConstruct
The PostConstruct annotation is used on a method that needs to be executed after dependency injection is done to perform any initialization.
Expecting the variable to be initialized inside the initialize does seem to work however.
According to the Initializable documentation, initialize is Called to initialize a controller after its root element has been completely processed.
Initializable
Order of call for initialize and #PostConstruct
I think it is safe to understand that the calling of initialize does not have anything to do with object construction. Instead, initialize is called when the root of the current node graph has been completely processed, so one can process things like event handlers etc. Something on the lines of document.onload or jQuery(document).ready(). If you were to try to attach event handlers before object graph is ready, there is a pretty good chance to see a null pointer because the node is not the object graph yet making it impossible to attach an event handler.
So, you'd instantiate an object (either directly or via injecting) before you load it to the scene-graph. Therefore #PostConstruct gets called before the initialize. But, if you instantiate the object directly then the responsibility to call the method annotated #PostConstruct falls on you, otherwise that post processing will not happen.
Conclusion:
It is safe to assume that initialize is always called after the method annotated with #PostConstruct.
EDIT
#Jewelsea has pointed out a few assumptions that I have not listed above. So here it goes, the circumstances where the above worked for me.
Using FXML files for views.
Controller name specified inside the fxml file.

Timing out from a bean

I want my session to timeout after a given interval of time. In web.xml I've been using code like:
<session-config>
<session-timeout>20</session-timeout>
</session-config>
where 20 is the timeout period in minutes, which works correctly.
What I would like to do is to do it programatically using code like this inside one of my beans as follow:
#ManagedBean(name="login")
#SessionScoped
public class MyLoginBean implements HttpSessionListener, Serializable {
// private variables etc.
HttpServletRequest request;
HttpSession session = request.getSession();
// Constructor
public MyLoginBean() {
session.setMaxInactiveInterval(1200);
}
// The rest of the code
}
where the timeout here is 1200 seconds, i.e. 20 minutes. Unfortunately, on opening up a browser to look at the application, it fails with the message:
com.sun.faces.mgbean.ManagedBeanCreationException: Cant instantiate class: com.csharp.MyLoginBean.
Followed by:
java.lang.NullPointerException
What am I doing wrong here? I know that setMaxInactiveInterval() refers to the particular session, which in this case is the login bean, rather than everything, which is what the code in web.xml file specifies. I have several beans, but timing out the login bean is the only one that matters.
I'm using JSF 2.0 with Glassfish 3.1.1 and Eclipse Indigo, so some advice would be very much appreciated.
The NullPointerException has an extremely simple cause. It's one of the most simplest exceptions. To learn about the cause of an arbitrary exception, just look in its javadoc. All Java exceptions have their causes explained in the javadoc. Here's an extract of the javadoc of NullPointerException:
Thrown when an application attempts to use null in a case where an object is required. These include:
Calling the instance method of a null object.
Accessing or modifying the field of a null object.
Taking the length of null as if it were an array.
Accessing or modifying the slots of null as if it were an array.
Throwing null as if it were a Throwable value.
Applications should throw instances of this class to indicate other illegal uses of the null object.
Your problem is caused by point 1. Here,
HttpServletRequest request;
HttpSession session = request.getSession();
you're trying to invoke getSession() method on null instead of a concrete HttpServletRequest instance. In fact, you should have obtained the HttpServletRequest via ExternalContext#getRequest() and assigned it to request.
However, you've bigger problems: you should absolutely not get hold of the current servlet request as a property of a session scoped bean (which lives longer than the HTTP request!). You should get it inside the thread local scope (i.e. wholly inside the constructor or the method block). You should also not let your JSF managed bean implement the HttpSessionListener. This makes no utter sense. You'd end up with 2 instances, one created as listener by the container and another one created as managed bean by JSF.
Just thus should do:
#ManagedBean(name="login")
#SessionScoped
public class MyLoginBean implements Serializable {
public MyLoginBean() {
HttpSession session = (HttpSession) FacesContext.getCurrentInstance().getExternalContext().getSession();
session.setMaxInactiveInterval(1200);
}
// ...
}
Or, if you're using JSF 2.1, use the one provided by ExternalContext:
FacesContext.getCurrentInstance().getExternalContext().setSessionMaxInactiveInterval(1200);

javax.ejb.NoSuchEJBException: Could not find stateful bean

I get the following error in my application:
2012-04-27 12:29:07,623 4540114 DEBUG [org.jboss.seam.jsf.SeamPhaseListener] (http-localhost%2F127.0.0.1-8080-3:) committing transaction after phase: INVOKE_APPLICATION 5
2012-04-27 12:29:07,623 4540114 DEBUG [org.jboss.seam.transaction.UTTransaction] (http-localhost%2F127.0.0.1-8080-3:) committing JTA transaction
2012-04-27 12:29:07,624 4540115 ERROR [org.jboss.aspects.tx.TxPolicy] (http-localhost%2F127.0.0.1-8080-3:) javax.ejb.NoSuchEJBException: Could not find stateful bean: a2d6v-rpg5ad-h1j0xu2n-1-h1j3g9no-cb
2012-04-27 12:29:07,624 4540115 WARN [org.jboss.seam.jsf.SeamPhaseListener] (http-localhost%2F127.0.0.1-8080-3:) uncaught exception, passing to exception handler
java.lang.IllegalStateException: Could not commit transaction
at org.jboss.seam.jsf.SeamPhaseListener.commitOrRollback(SeamPhaseListener.java:625)
While debugging I was successful in the application part and when it came to page redirect, this error occurs.
Can someone give me some pointers as to where it could be wrong?
I just had a similar problem, and it was all to do with the timeouts for the bean themselves.
You can either set timeouts on the stateful bean itself with the annotation
#CacheConfig (maxSize=100000, idleTimeoutSeconds=300, removalTimeoutSeconds=0)
Or by setting JBOSS_HOME\server\default\conf\standardjboss.xml to:
<container-configuration>
<container-name>Standard Stateful SessionBean</container-name>
...
<container-cache-conf>
...
<cache-policy-conf>
<remover-period>0</remover-period>
<max-bean-life>900</max-bean-life>
Where the parameters given are seconds.
I personally changed the standardjboss.xml to make it global. I made the remover-period 0 so that it's set to infinty. If it is less that the max bean life, then it's state will be removed you will get javax.ejb.NoSuchEJBException if the bean has not been touched.
Also worth checking you actually need a stateful bean hanging around.
https://community.jboss.org/wiki/howdothetimeoutsworkwithejb3statefulbeans
https://community.jboss.org/wiki/JbossTimeoutSettingForSeam
http://docs.jboss.org/seam/2.2.2.Final/reference/en-US/html_single/#d0e25223

Resources