EJB not recognized in enterprise application - jsf

I am working on Eclipse and I want to create an enterprise application using Glassfish and MySQL.
I created a Enterprise Application Project, with EJB and WEB modules, named WeatherEJB and WeatherWeb.
In the WeatherEJB project I generated entities from tables, using JPA and also I created a stateless remote session bean, called CountryDAO, which implements CountryDAOBean, in order to wrap over the generated entity Country.
In the WeatherWeb project I added references to the WeatherEJB project in the Java Build bath, project references and module dependencies.
Then, in the WeatherWeb project, I created a managed bean called CountryController (at 'request' scope), which looks like this:
import javax.ejb.EJB;
import model.Country;
import service.CountryDAO;
public class CountryController
{
#EJB
CountryDAO countryDao;
private Country country;
public CountryController()
{
country = new Country();
}
public String saveCountry()
{
String returnValue = "success";
try
{
countryDao.saveCountry(country);
}
catch (Exception e){
e.printStackTrace();
returnValue = "failure";
}
return returnValue;
}
public Country getCountry(){
return country;
}
public void setCountry(Country country){
this.country = country;
}
}
Although I can deploy successfully the application on Glassfish, when I try to access a jsf that uses the CountryController, I get the following errors:
type Exception report
message
descriptionThe server encountered an internal error () that prevented it from fulfilling this request.
exception
javax.servlet.ServletException: javax.faces.FacesException: com.sun.enterprise.InjectionException: Exception attempting to inject Unresolved Ejb-Ref managedBeans.CountryController/countryDao#jndi: service.CountryDAO#null#service.CountryDAO#Session#null into class managedBeans.CountryController
root cause
javax.faces.FacesException: javax.faces.FacesException: com.sun.enterprise.InjectionException: Exception attempting to inject Unresolved Ejb-Ref managedBeans.CountryController/countryDao#jndi: service.CountryDAO#null#service.CountryDAO#Session#null into class managedBeans.CountryController
root cause
javax.faces.FacesException: com.sun.enterprise.InjectionException: Exception attempting to inject Unresolved Ejb-Ref managedBeans.CountryController/countryDao#jndi: service.CountryDAO#null#service.CountryDAO#Session#null into class managedBeans.CountryController
root cause
com.sun.enterprise.InjectionException: Exception attempting to inject Unresolved Ejb-Ref managedBeans.CountryController/countryDao#jndi: service.CountryDAO#null#service.CountryDAO#Session#null into class managedBeans.CountryController
root cause
javax.naming.NameNotFoundException: service.CountryDAO#service.CountryDAO not found
What am I missing? or what am I doing wrong?

Actually, instead of the implementation class:
#EJB
CountryDAO countryDao;
I should have used the interface:
#EJB
CountryDAOBean countryDao;

Related

IllegalAccessException when accessing ZoneInfo via JSF/EL with JDK 17

While porting a big JEE8 application to Java 17, I stumbled upon an IllegalAccessException when rendering a simple EL expression: #{myWarBean.defaultTZ.rawOffset}. I managed to reproduce the problem in a SSCCE on github. When you run the application on Wildfly application server (I'm using 26.1.1.Final), you get the following stacktrace:
SEVERE [javax.enterprise.resource.webcontainer.jsf.application] (default task-1) Error Rendering View[/index.xhtml]: javax.el.ELException: /index.xhtml #23,74 value="raw offset=#{myWarBean.defaultTZ.rawOffset}": java.lang.IllegalAccessException: class javax.el.BeanELResolver cannot access class sun.util.calendar.ZoneInfo (in module java.base) because module java.base does not export sun.util.calendar to unnamed module #6a1cb0de
at com.sun.jsf-impl#2.3.17.SP01//com.sun.faces.facelets.el.TagValueExpression.getValue(TagValueExpression.java:77)
at javax.faces.api#3.1.0.SP01//javax.faces.component.ComponentStateHelper.eval(ComponentStateHelper.java:194)
at javax.faces.api#3.1.0.SP01//javax.faces.component.ComponentStateHelper.eval(ComponentStateHelper.java:181)
at javax.faces.api#3.1.0.SP01//javax.faces.component.UIOutput.getValue(UIOutput.java:140)
at com.sun.jsf-impl#2.3.17.SP01//com.sun.faces.renderkit.html_basic.HtmlBasicInputRenderer.getValue(HtmlBasicInputRenderer.java:198)
at com.sun.jsf-impl#2.3.17.SP01//com.sun.faces.renderkit.html_basic.HtmlBasicRenderer.getCurrentValue(HtmlBasicRenderer.java:328)
at com.sun.jsf-impl#2.3.17.SP01//com.sun.faces.renderkit.html_basic.HtmlBasicRenderer.encodeEnd(HtmlBasicRenderer.java:143)
at javax.faces.api#3.1.0.SP01//javax.faces.component.UIComponentBase.encodeEnd(UIComponentBase.java:600)
at com.sun.jsf-impl#2.3.17.SP01//com.sun.faces.renderkit.html_basic.HtmlBasicRenderer.encodeRecursive(HtmlBasicRenderer.java:286)
at com.sun.jsf-impl#2.3.17.SP01//com.sun.faces.renderkit.html_basic.GroupRenderer.encodeChildren(GroupRenderer.java:90)
at javax.faces.api#3.1.0.SP01//javax.faces.component.UIComponentBase.encodeChildren(UIComponentBase.java:571)
at javax.faces.api#3.1.0.SP01//javax.faces.component.UIComponent.encodeAll(UIComponent.java:1648)
at javax.faces.api#3.1.0.SP01//javax.faces.component.UIComponent.encodeAll(UIComponent.java:1651)
at javax.faces.api#3.1.0.SP01//javax.faces.component.UIComponent.encodeAll(UIComponent.java:1651)
at com.sun.jsf-impl#2.3.17.SP01//com.sun.faces.application.view.FaceletViewHandlingStrategy.renderView(FaceletViewHandlingStrategy.java:461)
[...]
Caused by: javax.el.ELException: java.lang.IllegalAccessException: class javax.el.BeanELResolver cannot access class sun.util.calendar.ZoneInfo (in module java.base) because module java.base does not export sun.util.calendar to unnamed module #6a1cb0de
at javax.el.api#2.0.0.Final//javax.el.BeanELResolver.getValue(BeanELResolver.java:193)
at com.sun.jsf-impl#2.3.17.SP01//com.sun.faces.el.DemuxCompositeELResolver._getValue(DemuxCompositeELResolver.java:156)
at com.sun.jsf-impl#2.3.17.SP01//com.sun.faces.el.DemuxCompositeELResolver.getValue(DemuxCompositeELResolver.java:184)
at org.glassfish.jakarta.el#3.0.3.jbossorg-4//com.sun.el.parser.AstValue.getValue(AstValue.java:114)
at org.glassfish.jakarta.el#3.0.3.jbossorg-4//com.sun.el.parser.AstValue.getValue(AstValue.java:177)
at org.glassfish.jakarta.el#3.0.3.jbossorg-4//com.sun.el.parser.AstDeferredExpression.getValue(AstDeferredExpression.java:39)
at org.glassfish.jakarta.el#3.0.3.jbossorg-4//com.sun.el.parser.AstCompositeExpression.getValue(AstCompositeExpression.java:44)
at org.glassfish.jakarta.el#3.0.3.jbossorg-4//com.sun.el.ValueExpressionImpl.getValue(ValueExpressionImpl.java:183)
at org.jboss.weld.core#3.1.9.Final//org.jboss.weld.module.web.el.WeldValueExpression.getValue(WeldValueExpression.java:50)
at org.jboss.weld.core#3.1.9.Final//org.jboss.weld.module.web.el.WeldValueExpression.getValue(WeldValueExpression.java:50)
at com.sun.jsf-impl#2.3.17.SP01//com.sun.faces.facelets.el.TagValueExpression.getValue(TagValueExpression.java:73)
... 73 more
Caused by: java.lang.IllegalAccessException: class javax.el.BeanELResolver cannot access class sun.util.calendar.ZoneInfo (in module java.base) because module java.base does not export sun.util.calendar to unnamed module #6a1cb0de
at java.base/jdk.internal.reflect.Reflection.newIllegalAccessException(Reflection.java:392)
at java.base/java.lang.reflect.AccessibleObject.checkAccess(AccessibleObject.java:674)
at java.base/java.lang.reflect.Method.invoke(Method.java:560)
at javax.el.api#2.0.0.Final//javax.el.BeanELResolver.getValue(BeanELResolver.java:186)
... 83 more
It seems, the problem is the EL expression accessing a java.util.TimeZone. The TimeZone class uses sun.util.calendar.ZoneInfo internally. And it seems this is not legal any more.
This only happens with Java 17. When running in Java 11, this all works fine.
I can workaround the exception by adding the following arguments when starting wildfly:
--add-exports=java.base/sun.util.calendar=ALL-UNNAMED
However, I think it should be possible to run the example without this workaround.
Any ideas what I'm missing? Might this even be a bug in Java/JDK 17?
It's reproducible with a plain Java application class as follows:
package com.stackoverflow.q72361100;
import java.lang.reflect.Method;
import java.util.TimeZone;
public class Test {
public static void main(String... args) throws Exception {
TimeZone instance = TimeZone.getDefault();
Class<?> cls = instance.getClass();
Method method = cls.getMethod("getRawOffset");
Object result = method.invoke(instance); // java.lang.IllegalAccessException
System.out.println(result);
}
}
The issue here is that instance.getClass() returns sun.util.calendar.ZoneInfo as that's the implementation returned by TimeZone#getDefault(). The work around would be to use TimeZone.class instead of instance.getClass():
package com.stackoverflow.q72361100;
import java.lang.reflect.Method;
import java.util.TimeZone;
public class Test {
public static void main(String... args) throws Exception {
TimeZone instance = TimeZone.getDefault();
Class<?> cls = TimeZone.class; // Work around
Method method = cls.getMethod("getRawOffset");
Object result = method.invoke(instance);
System.out.println(result);
}
}
I'd argue that this will require a change in EL spec. Ideally it should search further in declared super classes if the method is accessible as per Method#canAccess() and then use it instead.
package com.stackoverflow.q72361100;
import java.lang.reflect.Method;
import java.util.TimeZone;
public class Test {
public static void main(String... args) throws Exception {
TimeZone instance = TimeZone.getDefault();
Class<?> cls = instance.getClass();
Method method = getAccessibleMethod(instance, cls, "getRawOffset"); // Look in superclasses as well.
Object result = method.invoke(instance);
System.out.println(result);
}
private static Method getAccessibleMethod(Object instance, Class<?> cls, String methodName) throws NoSuchMethodException {
Method method = cls.getMethod(methodName);
if (method.canAccess(instance)) {
return method;
}
return getAccessibleMethod(instance, cls.getSuperclass(), methodName);
}
}
I've created an issue at EL spec: https://github.com/jakartaee/expression-language/issues/188
Until they get it fixed, you can work around it by adding a dedicated getter for it:
public int getDefaultTZrawOffset() {
return getDefaultTZ().getRawOffset();
}
#{myWarBean.defaultTZrawOffset}

UnsatisfiedResolutionException - CDI beans from Quarkus extensions

I'm working on a Quarkus Extension. But I have some problems to inject CDI Beans.
In the runtime module I have this class:
#ApplicationScoped
public class CustomRestClientBuilder{
//#Produces - Removed
//#ApplicationScoped - Removed
public RestClientBuilder newBuilder(String url) throws MalformedURLException {
return RestClientBuilder.newBuilder().baseUrl(new URL(url));
}
}
In the deployment module, I have this class:
class RestClientExtensionProcessor {
private static final String FEATURE = "rest-client-extension";
#BuildStep
FeatureBuildItem feature() {
return new FeatureBuildItem(FEATURE);
}
#BuildStep
public AdditionalBeanBuildItem producer() {
return new AdditionalBeanBuildItem(CustomRestClientBuilder.class);
}
}
And the problem appears in testing classes. I put the Test in Deployment module and it fails (however, in runtime module it works).
public class CustomRestClientBuilderTest {
#Inject
private CustomRestClientBuilder customRest;
#RegisterExtension
static final QuarkusUnitTest config = new QuarkusUnitTest()
.setArchiveProducer(() -> ShrinkWrap.create(JavaArchive.class));
#Test
public void testGreeting() {
IDummyRestClient restClient = customRest.newBuilder("url")
.build(IDummyRestClient.class);
}
}
The error is:
Build failed due to errors
[error]: Build step io.quarkus.arc.deployment.ArcProcessor#validate threw an exception:
javax.enterprise.inject.spi.DeploymentException: javax.enterprise.inject.UnsatisfiedResolutionException:
Unsatisfied dependency for type CustomRestClientBuilder and qualifiers [#Default]
I've checked this post before:
Exposing CDI beans from Quarkus extensions
UPDATED
This way is working (adding the class I need for testing). Does it makes sense?
#RegisterExtension
static final QuarkusUnitTest config = new QuarkusUnitTest()
.setArchiveProducer(() -> ShrinkWrap.create(JavaArchive.class)
.addClasses(CustomRestClientBuilder.class,
IDummyRestClient.class));

Error creating bean with name 'securityConfiguration': Unsatisfied dependency expressed through field 'myAppUserDetailsService';

Spring boot 1.5.3 project with test user-registry on H2 in memory DB
This is the Error Stacktrace
org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'securityConfiguration': Unsatisfied dependency expressed through field 'myAppUserDetailsService'; nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'SMRTUserService': Unsatisfied dependency expressed through field 'userInfoDAO'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'SMRTUserDAO': Injection of persistence dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'entityManagerFactory': Post-processing of FactoryBean's singleton object failed; nested exception is org.springframework.jdbc.datasource.init.ScriptStatementFailedException: Failed to execute SQL script statement #2 of URL [file:/C:/temp/SMRT/target/test-classes/data.sql]: ....
Can someone help me to understand the problem? I can't solve this errors.
Test Controller
public class CustomerControllerTest extends AbstractControllerTest {
#Test
#WithMockUser(roles = "ADMIN")
public void testShow() throws Exception {
mockMvc.perform(get("/customer/list")
.contentType(APPLICATION_JSON_UTF8))
.andExpect(status().isOk());
}
}
AbstractControllerTest
#RunWith(SpringRunner.class)
#SpringBootTest(webEnvironment = WebEnvironment.MOCK)
#AutoConfigureMockMvc
public abstract class AbstractControllerTest extends AbstractTest {
#Autowired protected MockMvc mockMvc;
#Autowired private FilterChainProxy filterChainProxy;
#Autowired private WebApplicationContext webApplicationContext;
#Before
public void setup() throws Exception {
MockitoAnnotations.initMocks(this);
this.mockMvc = webAppContextSetup(webApplicationContext)
.dispatchOptions(true)
.addFilters(filterChainProxy).build();
}
}
SecurityConfiguration
#Configuration
#EnableWebSecurity
#EnableGlobalMethodSecurity(prePostEnabled = true)
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
#Autowired private SMRTUserService myAppUserDetailsService;
#Autowired private BCryptPasswordEncoder bCryptPasswordEncoder;
#Bean
public BCryptPasswordEncoder passwordEncoder() {
BCryptPasswordEncoder bCryptPasswordEncoder = new BCryptPasswordEncoder();
return bCryptPasswordEncoder;
}
#Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(myAppUserDetailsService)
.passwordEncoder(bCryptPasswordEncoder);
}
}
SMRTUSerService
#Service
#Slf4j
public class SMRTUserService implements UserDetailsService {
#Autowired private ISMRTUserDAO userInfoDAO;
#Autowired private SMRTUserRepository smrtuserRepository;
...
}
Thanks
Well, your Exception already explains pretty well what the problem is:
Failed to execute SQL script statement #2 of URL [file:/C:/temp/SMRT/target/test-classes/data.sql]: ....
I asume you're importing some test data for your tests? There must be an error in your SQL statements.
if you are using keycloak for the authentification . you might get this error .
jhipster by default gives you 8090 as auth server , so you have to change it
Solution : 1 - start your keycloak server
2 - go to your jhipster project main->ressources->config->application.yml
change issuer ui by the port where your keycloak server is running : for example : issuer-uri: http://localhost:8080/auth/realms/demo
hope that was helpfull

PersistenceContextType.EXTENDED leads to failed lookup of Session Bean

I am upgrading from JBoss 7.1.1 to WildFly 8.1.0 and can't get rid of the error described below:
14:53:04,666 ERROR [org.jboss.as.ejb3.invocation] (default task-17) JBAS014134: EJB Invocation failed on component TransRbDAO for method public java.util.List de.bss.dm.kairos.db.kairosgui.TransRbDAO.findAll(): javax.ejb.EJBException: java.lang.IllegalStateException: JBAS011048: Failed to construct component instance
TransRbDAO is:
#Stateless
public class TransRbDAO extends AbstractDAO<TransRb> {
public List<TransRb> findAll() {
CriteriaBuilder cb = em.getCriteriaBuilder();
CriteriaQuery<TransRb> criteria = cb.createQuery(TransRb.class);
Root<TransRb> root = criteria.from(TransRb.class);
criteria.select(root);
return em.createQuery(criteria).getResultList();
}
}
with AbstractDAO like:
public class AbstractDAO<T> {
#Inject
#CsarGuiDBExtended
#PersistenceContext(unitName = "CSAR_GUI", type = PersistenceContextType.EXTENDED)
protected EntityManager em;
public T findById(Class<T> clazz, Object primaryKey) {
T i = em.find(clazz, primaryKey);
return i;
}
}
This construct works when using only #PersistenceContext(unitName = "CSAR_GUI"), except for the expected LazyInitializationException when accessing data on the JSF-page.
The root-cause for error above is:
Caused by: javax.naming.NamingException: JBAS011878: Failed to lookup env/de.bss.dm.kairos.db.kairosgui.AbstractDAO/em [Root exception is java.lang.ArrayIndexOutOfBoundsException]
at org.jboss.as.naming.ServiceBasedNamingStore.lookup(ServiceBasedNamingStore.java:144)
at org.jboss.as.naming.ServiceBasedNamingStore.lookup(ServiceBasedNamingStore.java:81)
Is this a bug in WildFly? Was this working only because of a bug in JBoss? Or am I doing something completely wrong?
Extended persistence context can only be used in stateful session beans.
See EJB 3.2 spec section 11.11.1.1 or this article:
http://docs.jboss.org/ejb3/app-server/tutorial/extended_pc/extended.html
It appears that the failing code was implemented in JBoss 7.2.0. At this time the setting
default-extended-persistence-inheritance was introduced. Along came the Method
static Map<String, ExtendedEntityManager> More ...getCurrentCall() {
ArrayList<Map<String, ExtendedEntityManager>> stack = currentSFSBCallStack();
Map<String, ExtendedEntityManager> result = null;
if (stack != null) {
result = stack.get(stack.size() - 1);
}
return result;
}
stack.get() was throwing the ArrayIndexOutOfBounds-Exception.
When setting default-extended-persistence-inheritance="DEEP" in standalone.xml and marking TransRbDAO #Stateful the error disappears.
I'm not sure whether it was a bug in JBoss 7.1.1 that I used, or if it is a bug since 7.2.0, clarification is appreciated ;)

Remote EJB call class not found exception

I'm trying to play around with EJB remote call but I'm getting an error. I have a web app called CallerApp that calls a method in another web app called RecieverApp.
In the CallerApp I have a remote interface:
#Remote
public interface ControllerRemote {
public int perform(int i);
}
and the call is performed in this class:
public class Talker {
#EJB private ControllerRemote remote;
//constructor and invoke setRemote() method to set remote
private void setRemote() throws Exception{
Properties p = new Properties();
Context jndiContext = new InitialContext(p);
Object ref = jndiContext.lookup("java:global/RecieverApp/Controller!bean.ControllerRemote");
remote = (ControllerRemote) PortableRemoteObject.narrow(ref, ControllerRemote.class);
}
public void action(){
remote.perform(5);
}
}
RecieverApp is depoloyed on the same Glassfish server:
#Stateless
public class Controller implements Serializable, ControllerRemote{
#Override
public int perform(int i){
//return something
}
}
The interface in RecieverApp is exactly as the one in CallerApp:
#Remote
public interface CallerRemote{
public int perform(int i);
}
I'm getting the following exception:
SEVERE: javax.naming.NamingException: Lookup failed for 'java:global/RecieverApp/Controller!bean.ControllerRemote'
in SerialContext[myEnv={java.naming.factory.initial=com.sun.enterprise.naming.impl.SerialInitContextFactory,
java.naming.factory.state=com.sun.corba.ee.impl.presentation.rmi.JNDIStateFactoryImpl,
java.naming.factory.url.pkgs=com.sun.enterprise.naming}
[Root exception is javax.naming.NamingException: ejb ref resolution error for remote business interfacebean.ControllerRemote
[Root exception is java.lang.ClassNotFoundException: bean.ControllerRemote]]
What I'm doing wrong here?
PS: I'm using Glassfish 3.1 and both applications are deployed on the same server.
There are few things to consider:
check whether JNDI name java:global/RecieverApp/Controller!bean.ControllerRemote exists, there was nice JNDI browser in Glassfish 2.x, but they didn't put it in GF 3 (it should be in GF 4), but you still have good old command line: asadmin list-jndi-entries
check whether your CallerRemote interfaces are in same packages in both applications
there is no need to perform both injection (#EJB) and JNDI lookup, if your class Talker is container-managed (i.e. bean, servlet, etc.) then #EJB annotation will suffice, otherwise use only lookup

Resources