Expression Language with CDI not work - glassfish

i have a simple ear file that includes a war. I have only one Named- Bean and one xhtml.
On glassfish all works fine. But on websphere it does not works.
I does not works mean all EL- Tag will be ignored. I can reproduce this in glassfish when i delete my beans.xml in /WEB- INF. I tried to put the beans.xml in every single folder.
And i read this (http://www.ibm.com/developerworks/websphere/techjournal/1301_stephen/1301_stephen.html):
The beans.xml file must be placed in one of these locations:
For a library JAR, EJB JAR, application client JAR or RAR archive, it needs to be in the META-INF directory.
The WEB-INF/classes directory of a WAR.
For a directory in the JVM classpath containing classes, the code will be scanned if the beans.xml file is located the META-INF sub-directory.
But nothing works. When i use #ManagedBean and Faces Session Scope instead all works fine.
I don't know what i can do else. Please help.
Here my example code and my structures:
XHTML:
<?xml version="1.0" encoding="UTF-8"?>
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:p="http://primefaces.org/ui">
<h:head>
</h:head>
<h:body>
<h:form id="tableform">
<h:outputText value="TEST"/>
<h:outputText value="#{personBean.helloWorld}"/>
<p:commandButton value="#{personBean.helloWorld}"/>
</h:form>
</h:body>
</html>
Bean:
#Named
#SessionScoped
public class PersonBean implements Serializable{
private String helloWorld;
#PostConstruct
public void init() {
setHelloWorld("HELLO WORLD");
}
public String getHelloWorld() {
return helloWorld;
}
public void setHelloWorld(String helloWorld) {
this.helloWorld = helloWorld;
}
}
Structure:
Ear
-Meta-Inf
--Application.xml
-WAR
--WEB-INF
---beans.xml
But i tried to put it in WEB-INF/classes, META-INF, META-INF from ear. Nothing works. :(
Result on Glassfish with beans.xml:
Result on Websphere / Glassfish without beans.xml:
I get no exception or error or something else.

WebSphere 8.x bundles JSF implementation (MyFaces) and only that default implementation works with CDI. You need to have beans.xml in WEB-INF folder.
However based on your page fragment, you are using custom one (PrimeFaces).
Check this page for more details : CDI integration with JavaServer Faces

Related

Glassfish does not detect the JAX-WS endpoint

Hello am facing a problem in the glassfish server
I have deployed my application with intellij and it has shown me the first page of the Hello World successfully and when I add to the url the name of the service a 404page has been shown
This is the code of the webservice
package test;
import javax.jws.WebMethod;
import javax.jws.WebService;
#WebService(serviceName = "HelloService")
public class Hello {
public Hello() {
}
#WebMethod()
public int calcul (int a , int b){
return a+b;
}
}
the web.xml
<!DOCTYPE web-app PUBLIC
"-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
"http://java.sun.com/dtd/web-app_2_3.dtd" >
<web-app>
<display-name>Archetype Created Web Application</display-name>
</web-app>
the index.jsp
<html>
<body>
<h1>Test the application the problem is that the glassfish can't access to the webservers</h1>
<h2>Hello World!</h2>
</body>
</html>
This is when I run the application for the first time
This is when I add the webservice name to the url
This is the Glassfish5 GUI showing it doesn't detect the components of the new webservices
After i tried again and again
I found in other WAR files that the web.xml don't exist
so i deleted the web.xml file and

Cannot migration from old 3.4.2 keycloak to latest version

I'm in charge of the migration of an old keycloak ( 3.4.2 ) to the latest version. I already migrated the database and the template.
The last thing that poses problem is custom providers for Account and Login.
I have two custom providers that extends :
FreeMarkerAccountProviderFactory
FreeMarkerLoginProviderFactory
At first, no providers was loaded at the starting of keycloak in version > 4.x. I investigate, and i found that override the default getId() method to return a value other than the default "freemarker" makes keycloak load them again.
But after that if i try to access the login page, i got a nullpointer exception on org.keycloak.services.resources.account.AccountFormService.init(AccountFormService.java:139)
Any idea ?
Edit : spi in provider are declared in META-INF/services and provider in standalone.xml
Edit 2 : I share the loginFormProvider as it as the same problem, trigger the same error but it less complicated in it's implementation
public class KeycloakFreeMarkerLoginFormsProvider extends FreeMarkerLoginFormProvider {
public KeycloakFreeMarkerLoginFormsProvider(KeycloakSession session, FreeMarkerUtil freeMarker) {
super(sesssion, freeMarker);
}
public Response createResponse(LoginFormsPages page) {
List<Foo> foo = // loading foo entities
List<Bar> bar = // loading bar entities
super.attributes.put("foo", foo);
super.attributes.put("bar", bar);
return super.createResponse(page);
}
}
public class KeycloakFreeMarkerLoginProviderFactory extends FreeMarkerLoginFormsProviderFactory {
private FreeMarkerUtil freeMarker;
public KeycloakFreeMarkerLoginProviderFactory() {
super();
}
#Override
public LoginFormsProvider create(KeycloakSession session) {
return new KeycloakFreeMarkerLoginFormsProvider(session, this.freeMarker);
}
#Override
public void init(Config.Scope config) {
this.freeMarker = new FreeMarkerUtil();
}
#Override
public void close() {
this.freeMarker = null;
}
/* Without getId() or with a value at freeMarker, the provider
is not load. With other value, get NPE */
#Override
public String getId() {
return "custom.provider";
}
}
Based on the comments chain, it appears that the problem is that the provider is not getting picked up by Keycloak. You have a couple of options for bundling a custom provider with Keycloak: as a module, or as a deployed war/ear/jar in the deployments directory.
Here's how to do it as a module:
You'll need to add some configuration (module.xml), and your jar, to the modules directory structure. It should look like something like this:
(keycloak root)
|- modules
|- system
|- layers
|- keycloak
|- com
|- yourcompany
|- yourmodule
|- main
|- your-module-name.jar
|- module.xml (see below)
Your module.xml should look something like this:
<?xml version="1.0" encoding="UTF-8"?>
<module name="com.yourcompany.yourmodule" xmlns="urn:jboss:module:1.6">
<resources>
<resource-root path="your-module-name.jar"/>
</resources>
<dependencies>
<!-- whatever module dependencies you need go here -->
<!-- these are just an example; you may or may not need them -->
<module name="org.jboss.logging" />
<module name="org.keycloak.keycloak-core"/>
<module name="org.keycloak.keycloak-services"/>
<module name="org.keycloak.keycloak-server-spi"/>
<module name="org.keycloak.keycloak-server-spi-private"/>
</dependencies>
</module>
Additionally, you'll need to configure standalone.xml and/or possibly standalone-ha.xml depending on your scenario (The default Keycloak Docker image uses -ha.xml by default). The pertinent section should look something like this:
<subsystem xmlns="urn:jboss:domain:keycloak-server:1.1">
<web-context>auth</web-context>
<providers>
<provider>
classpath:${jboss.home.dir}/providers/*
</provider>
<!-- add this -->
<provider>
module:com.yourcompany.yourmodule
</provider>
<!-- end add -->
</providers>
<master-realm-name>master</master-realm-name>
<scheduled-task-interval>900</scheduled-task-interval>
...
</subsystem>
Lastly, like you mention, you'll need the correct config in your META-INF/services directory: a file with the fully qualified classname of the ProviderFactory as defined by the SPI, with one line containing the fully qualified classname of your implementation. In your case, the file should be called org.keycloak.forms.login.LoginFormsProviderFactory and its value should be one line: (com.yourpackage).KeycloakFreeMarkerLoginProviderFactory
If it's picked up, you should be able to see it listed in the providers config in the admin UI. To view, log in to the admin console, click on your username in the upper right, and select "Server Info", then click on the "Providers" tab. You should see your provider listed under "login".

CDI doesn't work in a simple adapter

I've added the CDI feature to the server.xml file<feature>cdi-1.2</feature>.
My maven module contains the beans.xml inside the <module_name>/src/main/resources/META-INF folder.
This is the beans.xml content:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee
http://xmlns.jcp.org/xml/ns/javaee/beans_1_1.xsd"
version="1.1" bean-discovery-mode="all">
</beans>
But when I use the #Inject annotation it doesn't work, my bean is always null.
Code:
package ch.webapp.presentation;
...
#Path("/test/")
public class MyController {
#Inject
private MyService myService;
#GET
#Path("/foo/{count}")
#OAuthSecurity(scope = "login")
#Produces("application/json")
public Response news(#PathParam("count") int count) {
return Response
.ok(myService.getBar(count))
.build();
}
}
EDIT:
That's my bean
package ch.webapp.service;
...
#RequestScoped
public class MyService {
public String getBar(int count) {
return "foo";
}
}
I initialize jax-rs by extended the MFPJAXRSApplication class
package ch.webapp;
...
public class AccountApplication extends MFPJAXRSApplication {
#Override
protected void init() throws Exception {
}
#Override
protected void destroy() throws Exception {
}
#Override
protected String getPackageToScan() {
return getClass().getPackage().getName();
}
}
Environment details:
Launching mfp (WebSphere Application Server 8.5.5.8/wlp-1.0.11.cl50820151201-1942) on Java HotSpot(TM) 64-Bit Server VM, version 1.8.0_172-b11 (en_CH)
Console Product version: 8.0.0.00-20180717-175523
What's wrong?
First it seems that websphere jax-rs implementation does not integrate jax-rs resources automatically unless you annotate them appropriately.
Put the jax-rs in a CDI managed context by annotating it appropriately
#Path("/test/")
#javax.enterprise.context.RequestScoped
public class MyController {
#Inject
private MyService myService;
#GET
#Path("/foo/{count}")
#OAuthSecurity(scope = "login")
#Produces("application/json")
public Response news(#PathParam("count") int count) {
return Response
.ok(myService.getBar(count))
.build();
}
}
Also be sure that the annotation used for your service is
#javax.enterprise.context.RequestScoped
Based on the inputs provided by you please go through the below checklist.
Your services and controllers are in the same module and its packaging type is war, So you must place your beans.xml in this path src/main/resources/WEB-INF/beans.xml. (If this is Java EE 7 application then beans.xml is optional.
In your AccountApplication class try hardcoding the package name to ch.webapp.presentation
#Override
protected String getPackageToScan() {
return "ch.webapp.presentation";
}
This is just to check Behaviour of MFPJAXRSApplication.getPackageToScan() method whether it is scanning the specified package only or its child packages too.
Except these, everything seems fine to me. If this still doesn't work add complete application startup logs so that community can find the root cause of it.
This is classical mistake. CDI works for managed beans (for instance EJB's and servlets). If you want to enable it on your JAXRS bean, you have to make it "managed", that is annotate MyController as (for instance) javax.annotation.ManagedBean or as a javax.ejb.Stateless.
Also beware that in case of webapp (.war), the beans.xml file has to be located in the WEB-INF folder !

NPE with #Inject in WAR from a JPA utility jar

env: JBoss 7.1.1, jdk 1.7, WELD module upgraded to 1.1.10(just in case)
I have a JPA project that I am adding to the WEB-INF\lib directory. It contains my entities and DAO objects, which has the Entity Manager inject. I'm using custom annotations to qualify the PersistenceContext, which is Produced in a Resources class. I've run Arquillian tests in this project to ensure it works.
I have a beans.xml file in the \META-INF\ directory of the JPA jar and in the \WEB-INF\ directory of the war file. I even printed it out and put it on my desk, still didn't help.
Within my war file I have a class that is injecting a DAO object from the JPA jar. Its not working, its null.
I've found examples from the jboss (without jpa jar) with CDI and it works.
I've looked for examples but cannot find any with a jpa jar. Can anyone point me to where there is an example of a jee6 web app, with a JPA utility jar, that uses annotations to inject something from the JPA jar into the war classes?
Thank you very much for reading this plea.
--------------------additional info-----------------
structure of war file
META-INF
->maven
-->com.xyz
--->web
---->pom.properties
---->pom.xml
->MANIFEST.MF
WEB-INF
->classes
->lib
-->entities.jar
->beans.xml
->faces-config.xml
->web.xml
stack trace:
22:23:12,011 INFO [org.quartz.core.JobRunShell] (DefaultQuartzScheduler_Worker-2) Job DEFAULT.extractDir threw a JobExecutionException: : org.quartz.JobExecutionException: java.lang.NullPointerException [See nested exception: java.lang.NullPointerException]
at com.xyz.asp.commsrv.scheduler.jobs.DirScanJob.execute(DirScanJob.java:149) [classes:]
at org.quartz.core.JobRunShell.run(JobRunShell.java:213) [quartz-2.1.7.jar:]
at org.quartz.simpl.SimpleThreadPool$WorkerThread.run(SimpleThreadPool.java:557) [quartz-2.1.7.jar:]
Caused by: java.lang.NullPointerException
at com.xyz.asp.commsrv.scheduler.jobs.DirScanJob.execute(DirScanJob.java:140) [classes:]
... 2 more
This is the class that has the DAO object injected. This is a quartz scheduler job which is started by a ServletContextListener during jboss startup:
#DisallowConcurrentExecution
#PersistJobDataAfterExecution
public class DirScanJob implements Job{
...
#Inject
FiletracksentHome ftsHome;
#Override
public void execute(JobExecutionContext context) throw JobExecutionException{
...
BigDecimal bd = ftsHome.nextId()
}
}
This class resides in entities.jar:
#Stateless
public class FiletracksentHome{
#Inject
#DatabaseEntities
private EntityManager entityManager;
public BigDecimal nextId(){
...
}
}
CDI is available in the ServletContextListener but nothing within the context of the Quartz Scheduler. I didn't want to bother with another library, since CDI wasn't necessary. I injected some properties that I needed using the #Resource annotation within the ServletContextListener implementation ...
#Resource(lookup = "java:app/env/quartzjobdirectory")
private String quartzJobDirectory;
and within the web.xml ...
<env-entry>
<description>Quartz Jobs Directory</description>
<env-entry-name>java:app/env/quartzjobdirectory</env-entry-name>
<env-entry-type>java.lang.String</env-entry-type>
<env-entry-value>/appl/jboss-as-7.1.1.Final/standalone/configuration/quartz_jobs/</env-entry-value>
</env-entry>
And for the EJB calls within the Quartz Jobs because DI is not available I did some JNDI calls, such as ...
InitialContext ic = new InitialContext();
readyDocs = (ReadyDocumentsLocal) ic.lookup("java:global/commsrv-ear-1.0.0/commsrv-ejb-1.0.0/ReadyDocumentsBean!com.ista.asp.commsrv.ReadyDocumentsLocal");
and the EJB ...
#Stateless
public class ReadyDocumentsBean implements ReadyDocumentsLocal {
...
}
FYI ... jboss as 7.1 will output to the server.log the JNDI bindings for session beans.

How to execute a jar file on jboss7 startup?

I have a simple java class which displays "waiting" text on execution , in "TMSCore" java project.
package com.stock.bo;
public class example {
/**
* #param args
*/
public static void main(String[] args) {
// ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
System.out.println("================================> waiting");
}
}
I have created TMSCore.jar and have set this example.class as entry point ,of my jar file.
Then i have created a module for this project in C:\Jboss\jboss-as-7.1.1\modules\org\tms\main , and pasted the jar in the same path
then i have created module.xml and pasted in the same path
module.xml
<?xml version="1.0" encoding="UTF-8"?>
<module xmlns="urn:jboss:module:1.1" name="org.tms">
<resources>
<resource-root path="TMSCore.jar"/>
</resources>
</module>
then i have created a jboss-deployment-structure.xml in my webproject/web-inf directory
<?xml version="1.0" encoding="UTF-8"?>
<jboss-deployment-structure>
<deployment>
<dependencies>
<module name="org.tms"/>
</dependencies>
</deployment>
</jboss-deployment-structure>
when i start the server with my war containing above jboss-deployment-structure.xml, in my console its showing deployed TMSCore.jar
but my "waiting" text in my jar is not displayed on console
my requirement is i should get "================================> waiting" on my console once jboss is started up
or else can any one can suggest how to make a jar to execute on starting jboss server?
BTW i am using JBOSS7.1
If I am right it's because JBoss doesn't execute a library, it only loads the classes contained in the jar file. So putting a main function and generating an executable jar will not help.
If your goal is to have an global module on the server, I suggest you these modifications:
Create the module (as you have already done)
Declare it as dependency in jboss-deployment-structure.xml (as you have already done)
Declare it as global module on the server, so it will be loaded only once by JBoss. Edit the configuration file standalone.xml and modify the section:
<subsystem xmlns="urn:jboss:domain:ee:1.0">
<global-modules>
<module name="org.tms" />
</global-modules>
</subsystem>
Now you have a module that have classes loaded only once. I you need to have only one instance of your Example class, the I suggest you to use an singleton:
public class Example {
// The only one instance
private static Example instance;
// Private constructor to avoid creation of other instances of this class
private Example()
{
System.out.println("================================> waiting");
}
public static Example getInstance()
{
if(instance == null)
{
instance = new Example();
}
return instance;
}
}
Then to use it in all projects on the server
Example ex = Example.getInstance();
will give you back the existing instance (or create one the first time).
Notice: I can't try, so no guarantee that that will work.
Edit: Maybe a small modification of the Example class can also make it run during the classes loading:
public class Example {
// The only one instance
private static Example instance = new Example();
// Private constructor to avoid creation of other instances of this class
private Example()
{
System.out.println("================================> waiting");
}
public static Example getInstance()
{
return instance;
}
}
Again: not tested.
You can't run a jar, but you can execute a startup method in a singleton.
#Startup
#Singleton
public class FooBean {
#PostConstruct
void atStartup() { ... }
#PreDestroy
void atShutdown() { ... }
}
This will happen at application start up and shutdown. I'd call the function you need from there.
See http://docs.oracle.com/javaee/6/tutorial/doc/gipvi.html