How can I provide an own implementation of HttpAuthenticationMechanism in Open Liberty - open-liberty

In a simple app that I run on Open Liberty 21.0.0.8, I have provided an implementation of HttpAuthenticationMechanism:
// imports omitted
#CustomFormAuthenticationMechanismDefinition(
loginToContinue = #LoginToContinue(
loginPage = "/login.xhtml",
errorPage = "",
useForwardToLogin = false))
#ApplicationScoped
public class CustomAuthenticationMechanism implements HttpAuthenticationMechanism {
#Inject
private IdentityStoreHandler identityStoreHandler;
#Override
public AuthenticationStatus validateRequest(HttpServletRequest request,
HttpServletResponse response,
HttpMessageContext context) throws AuthenticationException {
Credential credential = context.getAuthParameters().getCredential();
if (credential != null) {
return context.notifyContainerAboutLogin(identityStoreHandler.validate(credential));
}
else {
return context.doNothing();
}
}
}
I expected Open Liberty to place that implementation of HttpAuthenticationMechanism into service.
However, on startup of Open Liberty a javax.enterprise.inject.spi.DeploymentException is thrown:
[INFO] [ERROR ] CWWKS1925E: The deployment for the dsgvo-management.war module in the dsgvo-management application failed because of multiple HttpAuthenticationMechanism implementations: de.knusperfisch.dsgvo.app.security.control.CustomAuthenticationMechanism, com.ibm.ws.security.javaeesec.cdi.beans.CustomFormAuthenticationMechanism. This failure is likely an application packaging issue. Make sure that each module has only one HttpAuthenticationMechanism implementation.
[INFO] [ERROR ] CWWKZ0004E: An exception occurred while starting the application dsgvo-management. The exception message was: com.ibm.ws.container.service.state.StateChangeException: org.jboss.weld.exceptions.DefinitionException: Exception List with 1 exceptions:
[INFO] Exception 0 :
[INFO] javax.enterprise.inject.spi.DeploymentException: CWWKS1925E: The deployment for the dsgvo-management.war module in the dsgvo-management application failed because of multiple HttpAuthenticationMechanism implementations: de.knusperfisch.dsgvo.app.security.control.CustomAuthenticationMechanism, com.ibm.ws.security.javaeesec.cdi.beans.CustomFormAuthenticationMechanism. This failure is likely an application packaging issue. Make sure that each module has only one HttpAuthenticationMechanism implementation.
[INFO] at com.ibm.ws.security.javaeesec.cdi.extensions.JavaEESecCDIExtension.verifyConfiguration(JavaEESecCDIExtension.java:893)
[INFO] at com.ibm.ws.security.javaeesec.cdi.extensions.JavaEESecCDIExtension.afterBeanDiscovery(JavaEESecCDIExtension.java:173)
The Java EE Security API states that:
An application MAY supply its own HttpAuthenticationMechanism, if desired.
and:
An HttpAuthenticationMechanism must be a CDI bean, and is therefore
visible to the container through CDI if it is packaged in a bean
archive, which generally include Java EE modules and application
archives [...]
It MUST be possible for the definition of an
HttpAuthenticationMechanism to exist within the application archive
[...]
Is there a way in Open Liberty to configure a specific HttpAuthenticationMechanism for an app from an application archive, and if so, how is this done?

At first glance, as the error message indicates, looks like there are multiple HttpAuthMechanisms active which is not allowed. Are there are any apps that are using the #CustomFormAuthenticationMechanismDefinition annotation which would bring in the default com.ibm.ws.security.javaeesec.cdi.beans.CustomFormAuthenticationMechanism AuthMech in addition to your CustomAuthenticationMechanism ?

Related

java.lang.Exception: HV000041: Call to TraversableResolver.isReachable() threw an exception

We are getting the below mentioned error on websphere 8.5
2020-01-07 15:19:37 [] DEBUG InvocableHandlerMethod.java.getMethodArgumentValues:174:
Could not resolve parameter [1] in public org.springframework.http.ResponseEntity
com.mycorp.uap.controller.WorkFlowController.updateTask(int,com.mycorp.uap.rest.vo.TaskVO)
throws java.lang.Exception: HV000041: Call to TraversableResolver.isReachable() threw an exception.
Method is defined as
public ResponseEntity<TaskVO> updateTask(#PathVariable("id") int taskId, #Valid #RequestBody(required=true) TaskVO task) throws Exception{
WEB-INF/lib contains the below jars related to hibernate, validation and spring
hibernate-commons-annotations-5.1.0.Final.jar
hibernate-core-5.4.4.Final.jar
hibernate-ehcache-5.4.4.Final.jar
hibernate-jpa-2.1-api-1.0.2.jar
hibernate-validator-6.0.15.Final.jar
validation-api-2.0.1.Final.jar
spring-aop-5.1.9.RELEASE.jar
spring-beans-5.1.9.RELEASE.jar
spring-context-5.1.9.RELEASE.jar
spring-context-support-5.1.9.RELEASE.jar
spring-core-5.1.9.RELEASE.jar
spring-data-commons-2.1.9.RELEASE.jar
spring-data-jpa-2.1.9.RELEASE.jar
spring-expression-5.1.9.RELEASE.jar
springfox-core-2.1.2.jar
springfox-schema-2.1.2.jar
springfox-spi-2.1.2.jar
springfox-spring-web-2.1.2.jar
springfox-swagger2-2.1.2.jar
springfox-swagger-common-2.1.2.jar
springfox-swagger-ui-2.1.2.jar
spring-hateoas-0.17.0.RELEASE.jar
spring-jcl-5.1.9.RELEASE.jar
spring-jdbc-5.1.9.RELEASE.jar
spring-ldap-core-2.3.2.RELEASE.jar
spring-messaging-5.1.9.RELEASE.jar
spring-orm-5.1.9.RELEASE.jar
spring-plugin-core-1.2.0.RELEASE.jar
spring-plugin-metadata-1.2.0.RELEASE.jar
spring-security-acl-5.1.6.RELEASE.jar
spring-security-cas-client.jar
spring-security-config-5.1.6.RELEASE.jar
spring-security-core-5.1.6.RELEASE.jar
spring-security-ldap-5.1.6.RELEASE.jar
spring-security-oauth2-2.3.6.RELEASE.jar
spring-security-openid-5.1.6.RELEASE.jar
spring-security-taglibs-5.1.6.RELEASE.jar
spring-security-web-5.1.6.RELEASE.jar
spring-test-5.1.9.RELEASE.jar
spring-tx-5.1.9.RELEASE.jar
spring-web-5.1.9.RELEASE.jar
spring-webmvc-5.1.9.RELEASE.jar
spring-websocket-5.1.9.RELEASE.jar
ParentLast setting is present in WebSphere configuration for our application so that WebSphere should give preference to the jars present in the WEB-INF/lib of our application
There is a similar method where #Valid is not present which works properly.
I looked into similar question on the stack overflow however could not quite get the correct solution.
What should be the correct solution?
Should we remove any jars from our WEB-INF/lib?
To fix this problem, you need to add the HibernatePersistenceProviderResolver class to your project:
HibernatePersistenceProviderResolver.java
and register it in the Application class in the onStartup method
#Override
public void onStartup(ServletContext servletContext) throws ServletException {
HibernatePersistenceProviderResolver.register();
...
}
Reference

Wiring Activiti as a Spring Bean in Grails

I'm trying to create a Grails application that uses Activiti for its process engine. To that end, I'd like the main Activiti service classes (RuntimeService, TaskService, etc.) to be wired as Spring beans.
I believe that I have the wiring setup correctly, but when I run a simple integration test that calls the runtime service, I get an error that Spring couldn't open a hibernate session (see Full Stack Trace, below).
Update: I can start the application with run-app, then call a controller action which calls my service, and it all works. So, the Activiti wiring works, it just has some conflict with the Grails Integration Testing mixin.
I really want the Activiti services to use the same datasource connection as the Grails application. I'm assuming that the problem is that Activiti is trying to create its own ConnectionHolder instance, when Grails already has one setup for the integration tests.
My specific (and possibly misguided) question I have is, how do I configure my Activiti ProcessEngine so that it uses the same data source and hibernate connection that my Grails application does?
The more general question is, how can I best make the Activiti services available to my Grails application? I've looked at the Activiti plugin for grails, and the source of it has helped me get this far. However, I'd rather not use that plugin; it's not using the latest activiti, development on it is not terribly active, and it's not really what I need in any case.
Full Stack Trace
| Failure: start approver request(com.package.MyServiceSpec)
| org.springframework.transaction.CannotCreateTransactionException: Could not open Hibernate Session for transaction; nested exception is java.lang.IllegalStateException: Already value [org.springframework.jdbc.datasource.ConnectionHolder#7f2e1821] for key [org.springframework.jdbc.datasource.LazyConnectionDa
at grails.test.mixin.integration.IntegrationTestMixin.initIntegrationTest(IntegrationTestMixin.groovy:58)
at org.spockframework.util.ReflectionUtil.invokeMethod(ReflectionUtil.java:138)
at org.spockframework.runtime.extension.builtin.JUnitFixtureMethodsExtension$FixtureType$FixtureMethodInterceptor.intercept(JUnitFixtureMethodsExtension.java:145)
at org.spockframework.runtime.extension.MethodInvocation.proceed(MethodInvocation.java:84)
at org.spockframework.util.ReflectionUtil.invokeMethod(ReflectionUtil.java:138)
at org.spockframework.util.ReflectionUtil.invokeMethod(ReflectionUtil.java:138)
at org.spockframework.util.ReflectionUtil.invokeMethod(ReflectionUtil.java:138)
Caused by: org.springframework.transaction.CannotCreateTransactionException: Could not open Hibernate Session for transaction; nested exception is java.lang.IllegalStateException: Already value [org.springframework.jdbc.datasource.ConnectionHolder#7f2e1821] for key [org.springframework.jdbc.datasource.LazyConn
... 7 more
Caused by: java.lang.IllegalStateException: Already value [org.springframework.jdbc.datasource.ConnectionHolder#7f2e1821] for key [org.springframework.jdbc.datasource.LazyConnectionDataSourceProxy#1b7aeb] bound to thread [main]
... 7 more
| Completed 1 integration test, 1 failed in 0m 1s
resources.groovy
import org.activiti.engine.ProcessEngine
import org.activiti.spring.ProcessEngineFactoryBean
import org.activiti.explorer.form.*
import org.activiti.spring.SpringProcessEngineConfiguration
import grails.util.Environment
//These imports are only needed in the test environment for building an h2 database for activiti during unit tests
import org.springframework.jdbc.datasource.DataSourceTransactionManager
import org.springframework.jdbc.datasource.SimpleDriverDataSource
beans = {
processEngineConfig(SpringProcessEngineConfiguration) {
dataSource = ref('dataSource')
transactionManager = ref('transactionManager')
databaseType = 'oracle'
databaseSchema = 'OURSCHEMA'
databaseSchemaUpdate = false
jobExecutorActivate = true
}
processEngine(ProcessEngineFactoryBean) {
processEngineConfiguration = ref("processEngineConfig")
}
runtimeService(processEngine: "getRuntimeService")
repositoryService(processEngine: "getRepositoryService")
taskService(processEngine: "getTaskService")
managementService(processEngine: "getManagementService")
historyService(processEngine: "getHistoryService")
formService(processEngine: "getFormService")
}
Service class
class MyService {
def foapAuthFoapService
def processEngine
def runtimeService
def repositoryService
def taskService
def managementService
def historyService
def formService
/**
* Start the activiti process.
*
*/
def startRequest(String requester, String subject, String designatedApprover) {
runtimeService.startProcessInstanceByKey('MyProcess', ["requester": requester, "subject": subject, "designatedApprover": designatedApprover])
}
}
Spock Test
def "start request"() {
setup:
def approverRequest = service.startRequest(requester, subject, designatedApprover)
def variables = runtimeService.getVariables(approverRequest.id) //approverRequest.getProcessVariables()
expect:
approverRequest instanceof ProcessInstance
variables.entrySet().contailsAll(["designatedApprover": designatedApprover, "requester": requester, "subject": subject].entrySet())
where:
requester | subject | designatedApprover
"abc123" | "def456"| "hij789"
}
we at Alephsa are maintaining the grails activiti plugin updated to the latest version of Activiti (5.17) and we are working to update to version 6. You can find the plugin at bintray also with the grails activiti spring security plugin. In our github account you can find the source code to guide you in your efforts.
Regards.

CODI with ejb stateless on Websphere liberty profile 8.5.5

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.

GlassFish can't initialize org.apache.cassandra.cql.jdbc.CassandraDriver

I'm trying to set up a connection pool in GlassFish for Cassandra using cassandra-jdbc driver. I've put the driver jar (and all of the jars that it depends on) in the ~glassfish-domain/lib/ext folder but I get the following error when I try to ping:
java.lang.NoClassDefFoundError: Could not initialize class org.apache.cassandra.cql.jdbc.CassandraDriver Could not initialize class org.apache.cassandra.cql.jdbc.CassandraDriver
It seems that GlassFish finds the class, but can't load it. As all of the dependencies are satisfied, a possible reason is that there is an exception in a static block. I checked the code of CassandraDriver and it actually has a static block:
static
{
// Register the CassandraDriver with DriverManager
try
{
CassandraDriver driverInst = new CassandraDriver();
DriverManager.registerDriver(driverInst);
}
catch (SQLException e)
{
throw new RuntimeException(e.getMessage());
}
}
Thanks in advance!
It seems that slf4j wasn't loading correctly because it depends on log4j.jar. So I after adding it in the classpath, everything seems to be working fine. Here's the list of all of the jars in my lib:
apache-cassandra-1.1.6.jar
apache-cassandra-clientutil-1.1.6.jar
apache-cassandra-thrift-1.1.6.jar
cassandra-jdbc-1.1.2.jar
commons-lang-2.4.jar
guava-r08.jar
libthrift-0.7.0.jar
log4j-1.2.14.jar
slf4j-api-1.5.8.jar
slf4j-log4j12-1.5.8.jar

How to prevent a Java EE app from starting when Spring DI fails

(I'm not sure if this question applies to Java EE apps in general or is Websphere-specific.)
When we get a Spring DI failure on apps we've deployed to WebSphere (a JNDI lookup failure, for example) the application still appears to have started successfully.
[15/02/11 17:21:22:495 GMT] 00000037 ContextLoader E org.springframework.web.context.ContextLoader initWebApplicationContext Context initialization failed
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'mybean' defined in
...big stack trace...
[15/02/11 17:21:22:526 GMT] 00000037 ApplicationMg A WSVR0221I: Application started: myapp
How can I make the application fail to start if exceptions are thrown during the spring initialisation?
Check if this helps. Based on that I'd guess it's application server-specific, but not sure.
Binding Spring context's lifecycle with an application's lifecycle should help.
Inside J2EE server Spring context is acquired mostly through the org.springframework.context.access.ContextSingletonBeanFactoryLocator (for example it is used by org.springframework.ejb.interceptor.SpringBeanAutowiringInterceptor). Invoking Spring context initialization eagerly on the application startup should do the job.
It could be done in the WebSphere specific way using Startup Beans:
#RemoteHome(AppStartUpHome.class)
#Stateless
public class SpringLifecycleBean {
private static Log logger = LogFactory.getLog(SpringLifecycleBean.class);
private static BeanFactoryReference bfr;
public boolean start() throws RemoteException {
logger.debug("Initializing spring context.");
try {
BeanFactoryLocator bfl = ContextSingletonBeanFactoryLocator.getInstance();
//hardcoded spring context's name (refactor for more complex use cases)
bfr = bfl.useBeanFactory("appContext");
} catch (Exception e) {
logger.error("Spring context startup failed", e);
return false;
}
return true;
}
public void stop() throws RemoteException {
if (bfr != null) {
logger.debug("Releasing spring context.");
bfr.release();
}
}
}
Adding a webapp module with javax.servlet.ServletContextListener containing similar code will also work.

Resources