CODI with ejb stateless on Websphere liberty profile 8.5.5 - websphere-liberty

I cannot launch a webapp that embedd CODI on websphere liberty profile 8.5.5 if the webapp contains a #Stateless ejb.
I get this exception:
[ERROR ] null
java.lang.reflect.InvocationTargetException
[ERROR ] An error occured while initializing MyFaces: java.lang.reflect.InvocationTargetException
java.lang.reflect.InvocationTargetException
[ERROR ] Uncaught.init.exception.thrown.by.servlet
Faces Servlet
codiTest
javax.enterprise.context.ContextNotActiveException: WebBeans context with scope type annotation #ApplicationScoped does not exist within current thread
at org.apache.webbeans.container.BeanManagerImpl.getContext(BeanManagerImpl.java:342)
at [internal classes]
at org.apache.myfaces.extensions.cdi.core.api.config.CodiCoreConfig_$$_javassist_78.isAdvancedQualifierRequiredForDependencyInjection(CodiCoreConfig_$$_javassist_78.java)
at org.apache.myfaces.extensions.cdi.jsf.impl.listener.phase.PhaseListenerExtension.consumePhaseListeners(PhaseListenerExtension.java:110)
at org.apache.myfaces.extensions.cdi.jsf2.impl.listener.phase.CodiLifecycleFactoryWrapper.getLifecycle(CodiLifecycleFactoryWrapper.java:67)
at javax.faces.webapp.FacesServlet.init(FacesServlet.java:119)
at com.ibm.ws.webcontainer.servlet.ServletWrapper.init(ServletWrapper.java:322)
at [internal classes]
[ERROR ] SRVE0266E: Error occured while initializing servlets: javax.servlet.ServletException: SRVE0207E: Uncaught initialization exception created by servlet
at com.ibm.ws.webcontainer.servlet.ServletWrapper.init(ServletWrapper.java:385)
at [internal classes]
Caused by: javax.enterprise.context.ContextNotActiveException: WebBeans context with scope type annotation #ApplicationScoped does not exist within current thread
at org.apache.webbeans.container.BeanManagerImpl.getContext(BeanManagerImpl.java:342)
at [internal classes]
at org.apache.myfaces.extensions.cdi.core.api.config.CodiCoreConfig_$$_javassist_78.isAdvancedQualifierRequiredForDependencyInjection(CodiCoreConfig_$$_javassist_78.java)
at org.apache.myfaces.extensions.cdi.jsf.impl.listener.phase.PhaseListenerExtension.consumePhaseListeners(PhaseListenerExtension.java:110)
at org.apache.myfaces.extensions.cdi.jsf2.impl.listener.phase.CodiLifecycleFactoryWrapper.getLifecycle(CodiLifecycleFactoryWrapper.java:67)
at javax.faces.webapp.FacesServlet.init(FacesServlet.java:119)
at com.ibm.ws.webcontainer.servlet.ServletWrapper.init(ServletWrapper.java:322)
... 1 more
[WARNING ] Unknown RenderKit 'HTML_BASIC'.
[WARNING ] Unknown RenderKit 'HTML_BASIC'.
[ERROR ] An exception occurred
java.lang.IllegalArgumentException: Could not find a RenderKit for "HTML_BASIC"
I've constated that the problem occurs only if an ejb is present in the project (in my case a #Stateless ejb).
In this case, the application context is initialized when the server is started and the webapp installed/deployed. No problem here.
When the first HTTP request is handled by the webapp, the FacesServlet is initialized and CodiNavigationHandler is instanciated.
The method CodiNavigationHandler.isAddViewConfigsAsNavigationCaseActivated() is called in the constructor and tries to get a reference on CODI JsfModuleConfig. This JsfModuleConfig has an #ApplicationScoped annotation and the the beanManager tries to get the application context.
This application context has already been created (when the webapp is deployed) but the LibertyContextsService.initApplicationContext(String)has not been called yet.
So the application context is null on the LibertyContextsService.applicationContexts ThreadLocal variable and the error occurs:
WebBeans context with scope type annotation #ApplicationScoped does not exist within current thread
To reproduce:
create a Dynamic Web Project
add an almost empty beans.xml under WEB-INF (just a beans element)
add an almost empty faces-config.xml under WEB-INF (just a faces-config element)
add a web.xml with a faces/index.xhtml
copy codi jars in WEB-INF/lib (http://www.apache.org/dyn/closer.cgi/myfaces/binaries/myfaces-extcdi-assembly-jsf20-1.0.5-bin.zip)
add a stateless bean:
import javax.annotation.PostConstruct;
import javax.ejb.Stateless;
#Stateless
public class MyBean {
#PostConstruct
public void postConstruct() {
System.out.println("post construct: " + this);
}
public String getTitle() {
return "test";
}
}
add a jsf bean:
import javax.inject.Inject;
import javax.inject.Named;
#Named
public class MyController {
#Inject
private MyBean myBean;
public String getTitle() {
return myBean.getTitle();
}
}
add a simple jsf web page with:
<h:body>
<h:outputText>${myController.title}</h:outputText>
</h:body>
nota: if you remove the #stateless on the ejb, the application works.

Effectively it seems to be a bug (I also post the question on IBM forums: https://www.ibm.com/developerworks/community/forums/html/topic?id=f372bbc5-5ba4-4c2a-9ef0-0bdcd76766da#09228314-2baf-4892-899e-5a8cc52daa19).
I'm going to try to find a way to create a PMR (I'm in a big company, difficult to find the right person that will grant me access to that).
So for now, I've switched to jboss.

Related

why jdk proxy could not be injected

I use Aspect like this:
#Aspect
#Component
public class DataSourceAspect {
#Pointcut("#target(com.chen.dynamicsource.aspect.DataSource)")
public void pointCut() {
}
#Before("pointCut()")
public void doBefore(JoinPoint joinPoint) {}
}
And I add it to application.yml:
spring
aop:
proxy-target-class: false
When I run the application. I get the following error:
***************************
APPLICATION FAILED TO START
***************************
Description:
The bean 'dispatcherServlet' could not be injected because it is a JDK dynamic proxy
The bean is of type 'com.sun.proxy.$Proxy67' and implements:
org.springframework.context.ApplicationContextAware
org.springframework.core.env.EnvironmentCapable
org.springframework.context.EnvironmentAware
javax.servlet.Servlet
javax.servlet.ServletConfig
java.io.Serializable
org.springframework.aop.SpringProxy
org.springframework.aop.framework.Advised
org.springframework.core.DecoratingProxy
Expected a bean of type 'org.springframework.web.servlet.DispatcherServlet' which implements:
I know I can use statically evaluated pointcut designators like within () and change the value of proxy-target-class to true to avoid the problem.
But I just want to know why jdk proxy could not be injected.

Wildfly / Infinispan HTTP session replication hits ClassNotFoundException when unmarshalling CGLIB Session Bean

I'm running Wildfly 20.0.1.Final in standalone, two-node cluster. I'm trying to implement HTTP Session sharing between the nodes.
In my Spring web application I have <distributable/> in my web.xml.
My session object is this:
package my.package;
#Component
#Scope(value = WebApplicationContext.SCOPE_SESSION, proxyMode = ScopedProxyMode.INTERFACES)
public class MySessionBean implements Serializable {
// omitted for brevity
}
As you can see, I have ScopedProxyMode.TARGET_CLASS.
When I perform a failover in Wildfly, my HTTP Session can't be restored however, as I hit this warning:
2021-02-22 13:24:18,651 WARN [org.wildfly.clustering.web.infinispan] (default task-1) WFLYCLWEBINF0007:
Failed to activate attributes of session Pd9oI0OBiZSC9we0uXsZdBwkLnadO1l4TUfvoJZf:
org.wildfly.clustering.marshalling.spi.InvalidSerializedFormException:
java.lang.ClassNotFoundException: my.package.MySessionBean$$EnhancerBySpringCGLIB$$9c0fa1df
from [Module "deployment.myDeployment.war" from Service Module Loader]
...
Caused by: java.lang.ClassNotFoundException: my.package.MySessionBean$$EnhancerBySpringCGLIB$$9c0fa1df from [Module "deployment.myDeployment.war" from Service Module Loader]
at org.jboss.modules.ModuleClassLoader.findClass(ModuleClassLoader.java:255)
at org.jboss.modules.ConcurrentClassLoader.performLoadClassUnchecked(ConcurrentClassLoader.java:410)
at org.jboss.modules.ConcurrentClassLoader.performLoadClass(ConcurrentClassLoader.java:398)
at org.jboss.modules.ConcurrentClassLoader.loadClass(ConcurrentClassLoader.java:116)
at java.base/java.lang.Class.forName0(Native Method)
at java.base/java.lang.Class.forName(Class.java:398)
at org.jboss.marshalling#2.0.9.Final//org.jboss.marshalling.ModularClassResolver.resolveClass(ModularClassResolver.java:133)
at org.jboss.marshalling.river#2.0.9.Final//org.jboss.marshalling.river.RiverUnmarshaller.doReadClassDescriptor(RiverUnmarshaller.java:1033)
at org.jboss.marshalling.river#2.0.9.Final//org.jboss.marshalling.river.RiverUnmarshaller.doReadNewObject(RiverUnmarshaller.java:1366)
at org.jboss.marshalling.river#2.0.9.Final//org.jboss.marshalling.river.RiverUnmarshaller.doReadObject(RiverUnmarshaller.java:283)
at org.jboss.marshalling.river#2.0.9.Final//org.jboss.marshalling.river.RiverUnmarshaller.doReadObject(RiverUnmarshaller.java:216)
at org.jboss.marshalling#2.0.9.Final//org.jboss.marshalling.AbstractObjectInput.readObject(AbstractObjectInput.java:41)
at org.wildfly.clustering.marshalling.spi#20.0.1.Final//org.wildfly.clustering.marshalling.spi.util.MapExternalizer.readObject(MapExternalizer.java:65)
...
Note, that the ClassNotFoundException is complaining because the lack of my.package.MySessionBean$$EnhancerBySpringCGLIB$$9c0fa1df, which is the Spring-enhanced bean of my MySessionBean bean.
Changing to ScopedProxyMode.INTERFACES is not an option.
Can you please point me in the right direction with this?
I managed to fix this by creating a simple POJO, called MySessionDTO, and using that in my session.
So initially I had this (which threw the exception in the question):
request.getSession().setAttribute("mySession", mySessionBean);
...and after I created MySessionDTO (see below), I refactored it into this:
request.getSession().setAttribute("mySession", mySessionBean.getMySessionDTO());
MySessionDTO is a simple POJO:
package my.package;
import java.io.Serializable;
public class MySessionDTO extends MySessionBean implements Serializable {
public MySessionDTO (MySessionBean mySessionBean) {
this.setAttributeX(mySessionBean.getAttributeX());
this.setAttributeY(mySessionBean.getAttributeY());
}
}

java.lang.IllegalArgumentException: A ServletContext is required to configure default servlet handling

I have the following test class:
#ActiveProfiles({ "DataTC", "test" })
#RunWith(SpringJUnit4ClassRunner.class)
#ContextConfiguration(classes = {BaseTestConfiguration.class, DataTestConfiguration.class, JpaConfiguration.class, PropertyPlaceholderConfiguration.class })
public class RegularDayToTimeSlotsTest {
...
The issue seems to come from the BaseTestConfiguration class:
#Configuration
#ComponentScan(basePackages = { "com.bignibou" }, excludeFilters = { #Filter(type = FilterType.CUSTOM, value = RooRegexFilter.class),
#Filter(type = FilterType.ANNOTATION, value = Controller.class), #Filter(type = FilterType.ANNOTATION, value = ControllerAdvice.class) })
public class BaseTestConfiguration {
}
I systematically get this exception:
Caused by: java.lang.IllegalArgumentException: A ServletContext is required to configure default servlet handling
at org.springframework.util.Assert.notNull(Assert.java:112)
at org.springframework.web.servlet.config.annotation.DefaultServletHandlerConfigurer.<init>(DefaultServletHandlerConfigurer.java:54)
at org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport.defaultServletHandlerMapping(WebMvcConfigurationSupport.java:329)
at org.springframework.web.servlet.config.annotation.DelegatingWebMvcConfiguration$$EnhancerByCGLIB$$bb4ceb44.CGLIB$defaultServletHandlerMapping$22(<generated>)
at org.springframework.web.servlet.config.annotation.DelegatingWebMvcConfiguration$$EnhancerByCGLIB$$bb4ceb44$$FastClassByCGLIB$$368bb5c1.invoke(<generated>)
at org.springframework.cglib.proxy.MethodProxy.invokeSuper(MethodProxy.java:228)
at org.springframework.context.annotation.ConfigurationClassEnhancer$BeanMethodInterceptor.intercept(ConfigurationClassEnhancer.java:326)
at org.springframework.web.servlet.config.annotation.DelegatingWebMvcConfiguration$$EnhancerByCGLIB$$bb4ceb44.defaultServletHandlerMapping(<generated>)
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:606)
at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:166)
... 43 more
I am not sure how to get around this issue. Somehow Spring is looking for a ServletContext when I run the test and I get the above exception...
One of your #Configuration classes is obviously annotated with #EnableWebMvc. That's how DelegatingWebMvcConfiguration ends up in your stack trace, since it is imported by #EnableWebMvc.
So although you think you don't need a WebApplicationContext (and hence a ServletContext), you in fact do need it simply because you are loading an application context with #EnableWebMvc.
You have two options:
Compose the configuration classes for your integration test so that you are not including the web-related configuration (i.e., the #Configuration class(es) annotated with #EnableWebMvc).
Annotate your test class with #WebAppConfiguration as suggested in other comments above.
Regards,
Sam (author of the Spring TestContext Framework)
It seems like you are missing
#WebAppConfiguration
from your test class.
The documentation states
The resource base path is used behind the scenes to create a
MockServletContext which serves as the ServletContext for the test’s
WebApplicationContext.
Typically a Servlet container would provide the ServletContext. Since you are in a testing environment, you need a fake. #WebAppConfiguration provides that.
For you to instantiate the Servlet context, you would have to use the annotation.
#WebAppConfiguration
A class-level annotation that is used to declare that the ApplicationContext loaded for an integration test should be a WebApplicationContext. The mere presence of #WebAppConfiguration on a test class ensures that a WebApplicationContext will be loaded for the test, using the default value of "file:src/main/webapp" for the path to the root of the web application (i.e., the resource base path). The resource base path is used behind the scenes to create a MockServletContext which serves as the ServletContext for the test’s WebApplicationContext.
I was getting a similar error but whilst running the application normally rather than trying to run tests.
It turns out if you're making use of a custom PermissionEvaluator then you need to declare it in a separate #Configuration class to the one with your main Spring security configuration in.
See: How do I add method based security to a Spring Boot project?
There is also an open Github issue: https://github.com/spring-projects/spring-boot/issues/4875

Hibernate - Spring, SessionFactory nullPointerException (when calling getCurrentSession())

I try to save my PartageDomain in my database using hibernate session factory, the problem is that in Session session = sessionFactory.getCurrentSession(); a nullPointerException is thrown. My dataSource is well configured, and I can already save/persist other objects with exactly the same way in this project, so I don't khow where the problem comes from.
a snapshot from the console exception :
javax.faces.FacesException: /pages/indexx.xhtml #28,72 listener="#{userMB.saveUserRights}": java.lang.NullPointerException
at com.sun.faces.lifecycle.InvokeApplicationPhase.execute(InvokeApplicationPhase.java:85)
at com.sun.faces.lifecycle.Phase.doPhase(Phase.java:97)
at com.sun.faces.lifecycle.LifecycleImpl.execute(LifecycleImpl.java:114)
.....
javax.el.ELException: /pages/indexx.xhtml #28,72 listener="#{userMB.saveUserRights}": java.lang.NullPointerException
at com.sun.faces.facelets.el.TagMethodExpression.invoke(TagMethodExpression.java:108)
at com.sun.faces.facelets.tag.jsf.core.AjaxBehaviorListenerImpl.processAjaxBehavior(AjaxHandler.java:447)
at javax.faces.event.AjaxBehaviorEvent.processListener(AjaxBehaviorEvent.java:109)
at javax.faces.component.behavior.BehaviorBase.broadcast(BehaviorBase.java:98)
at javax.faces.component.UIComponentBase.broadcast(UIComponentBase.java:764)
at javax.faces.component.UIData.broadcast(UIData.java:911)
...
Caused by: java.lang.NullPointerException
at com.stage.dao.PartageDaoImpl.add(PartageDaoImpl.java:35)
at com.stage.beans.UserManagedBean.saveUserRights(UserManagedBean.java:224)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at com.sun.el.parser.AstValue.invoke(AstValue.java:234)
at com.sun.el.MethodExpressionImpl.invoke(MethodExpressionImpl.java:297)
at com.sun.faces.facelets.el.TagMethodExpression.invoke(TagMethodExpression.java:102)
... 23 more
here is part of code from the partageDomainImpl class :
#Repository
public class PartageDaoImpl implements PartageDao, Serializable {
#Resource(name = "sessionFactory")
private SessionFactory sessionFactory;
// sessionFactory getter and setter :)
public void add(PartageDomain partageDomain) { System.out.println(partageDomain.getPartageId().getUserDomain().getFirstName()); // I get this
Session session = sessionFactory.getCurrentSession();
// Save
try {
session.persist(partageDomain);
} catch (Exception e) {
session.saveOrUpdate(partageDomain);
}
}
Note that the exception is not caused by the EL langage, in fact I get the object correctly by printing it before calling the getsessionFactory method from which come the exception
in my PartageDomain class I have :
#Entity
public class PartageDomain implements Serializable {
// the PartageDomain properties, getters and setters ....
In fact I'm showing that to you to mention that I'm using annotation to manage dependencies and injections, concerning my session factory, I declared it in my configuration file as
<bean id="sessionFactory" class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean"
p:dataSource-ref="dataSource"
p:configLocation="${hibernate.config}"
p:packagesToScan="com.stage"/>
I finally found the problem, in fact, it's my partageServiceImpl that has the sessionfactory property managed by spring-hibernate injection system.
In my userManagedBean, I was calling directly the the PartageDaoImpl.add method to add the partageDomain object, the correct thing is to call the PartageServiceImpl.add which has the sessionFactory property, in this whay the currentSession will not be null
I admit that it's a grave error that I made and It costs to me the whole day trying to solving it, so I hope this error will be faslty corrected by the others when seeying the exception that I have.
Just a guess -
It is possible that you have a conflict in your context files.
I think that your #Repository annotated bean is somehow being created in the servlet application context, while <tx:annotation-driven transaction-manager="transactionManager" /> is declared in the root web app context.
In other words the #Transactional works only in the context where tx:annotation-driven is declared.
I suppose that it's possible for some the beans to be autoscanned and created twice making them to exist both in the web application and servlet application contexts, if autoscanning is present in both context configurations.
So the solution may be to check that all beans are created once and in the right places - DAOs in the root context, Controllers in the servlet context etc.
update
Also please note that this code uses catch em all exception handling antipattern and possibly accesses hibernate session after it has raised an exception which is not supported by Hibernate as I know.

Proxy Exception while injecting spring bean into JSF bean

I'm trying to inject spring bean into JSF bean, I'm using Spring 3.1 and JSF 2 (Mojarra 2.1.7)
Without a lot of talking my configuration and code and exception listed in the following:
StudentService.java:
#Scope(proxyMode=ScopedProxyMode.TARGET_CLASS)
public class StudentsService extends AbstractMaqraaService {
#Override
public Set<Class<?>> getTypes() {
// TODO Auto-generated method stub
return null;
}
public Student registerStudent(Student student) {
return this.store(student);
}
}
StudentRegistrationMBean.java:
#ManagedBean(name="studentRegistrationMBean")
#SessionScoped
public class StudentRegistrationMBean extends AbstractMBean {
private Student student;
#ManagedProperty (value="#{studentsService}")
private StudentsService studentsService;
public StudentRegistrationMBean() {
this.student = new Student();
}
/*Setters and getters omitted here only*/
public String register() {
studentsService.registerStudent(student);
return "manageStudents";
}
}
Spring bean in module context xml file:
<bean id="abstractMaqraaService" class="org.tts.maqraa.service.AbstractMaqraaService" abstract="true"/>
<bean id="studentsService" class="org.tts.maqraa.service.StudentsService" lazy-init="default" parent="abstractMaqraaService"/>
faces-config.xml:
...
<application>
<el-resolver>org.springframework.web.jsf.el.SpringBeanFacesELResolver</el-resolver>
</application>
...
Eception:
TRACE [http-bio-8080-exec-3] (SpringBeanELResolver.java:53) - Successfully resolved variable 'studentsService' in Spring BeanFactory
DEBUG [http-bio-8080-exec-3] (AbstractBeanFactory.java:245) - Returning cached instance of singleton bean 'studentsService'
نوار 13, 2012 11:10:45 ص com.sun.faces.application.view.FaceletViewHandlingStrategy handleRenderException
SEVERE: Error Rendering View[/teacher/registerNewStudent.xhtml]
com.sun.faces.mgbean.ManagedBeanCreationException: Unable to set property studentsService for managed bean studentRegistrationMBean
at com.sun.faces.mgbean.ManagedBeanBuilder$BakedBeanProperty.set(ManagedBeanBuilder.java:615)
at com.sun.faces.mgbean.ManagedBeanBuilder.buildBean(ManagedBeanBuilder.java:133)
...
at java.lang.Thread.run(Unknown Source)
Caused by: javax.el.ELException: Cannot convert org.tts.maqraa.service.StudentsService#8f65bc0 of type class $Proxy10 to class org.tts.maqraa.service.StudentsService
at org.apache.el.lang.ELSupport.coerceToType(ELSupport.java:420)
at org.apache.el.ExpressionFactoryImpl.coerceToType(ExpressionFactoryImpl.java:47)
at com.sun.faces.el.ELUtils.coerce(ELUtils.java:536)
at com.sun.faces.mgbean.BeanBuilder$Expression.evaluate(BeanBuilder.java:592)
at com.sun.faces.mgbean.ManagedBeanBuilder$BakedBeanProperty.set(ManagedBeanBuilder.java:606)
... 47 more
ERROR [http-bio-8080-exec-3] (MaqraaExceptionHandler.java:83) - Exception
javax.el.ELException: Cannot convert org.tts.maqraa.service.StudentsService#8f65bc0 of type class $Proxy10 to class org.tts.maqraa.service.StudentsService
at org.apache.el.lang.ELSupport.coerceToType(ELSupport.java:420)
...
at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
at java.lang.Thread.run(Unknown Source)
I made a lot of search in Google and found a lot of questions here had issues like mine but nothing helped me, I hope I'll find my solution for my special case !!
use <aop:aspectj-autoproxy proxy-target-class="true"/> to enforce use of JDK proxy rather than CGLIB
if you inject your Spring service like this don't forget to create the setter for your Service:
#ManagedProperty (value="#{studentsService}")
private StudentsService studentsService;
public void setStudentsService (StudentsService studentsService)
{
this.studentsService = studentsService;
}
With the #Autowired annotation there was no need to do this.
Take a look at this answer It's about not using an interface for using your proxy.

Resources