EJB java.lang.ClassCastException - java

I'm using Eclipse with Glassfish for my first steps in Java EE. I've created three eclipse projects (JPA project, EJB project, Web project). I've created a local EJB bean TestBean with a local interface TestBeanLocal:
#Stateless
#LocalBean
class TestBean implements TestBeanLocal {
#Override
public void doSomething(List<JPAEntity> myEntities) {
for(JPAEntity a : myEntities) {
}
}
}
and a ManagedBean that uses the EJB:
#MangagedBean
public class MyBean {
#EJB
private TestBeanLocal testBean;
#PostConstruct
private void init() {
//load JPAEntity from Database
List<JPAEntity> myEntities = ....
testBean.doSomething(myEntities);
}
}
My problem is that I get a ClassCastException at the for loop in the TestBean.
java.lang.ClassCastException: us.mypackage.jpa.JPAEntity cannot be cast to us.mypackage.jpa.JPAEntity
I found another stackoverflow question that says that this error message is because of two different classloaders. How can I fix this? Can I tell EJB to use the same classloader that my webproject uses?

It seems that the entity jar is located in both war and ear
Try to remove the entity jar from the war library
War should see the ear libraries file
HTH

Related

EJBConfigurationException on Websphere Liberty Base 17

I have to migrate a software project from Websphere Application Server v8 (WAS8) to Webphere Liberty Base v17 (WL17) and ran into troubles with the EJB's. E.g. there is the following EJB:
#Stateless
#Local(MyUserServiceLocal.class)
public class MyUserServiceBean implements MyUserServiceLocal {
#EJB
private OtherServiceLocal otherServiceLocal;
#Resource
private SessionContext context;
public MyUserServiceBean() {
}
public String getUserEmail() {...}
public String getUserDataId() throws ServiceException {...}
...
}
With the corresponding local interface:
#Local
public interface MyUserServiceLocal {
public String getUserEmail();
public String getUserDataId() throws ServiceException;
...
}
There are a lot more EJB's following a similar implementation scheme.
The project builds fine, all facets in all Eclipse projects are set correctly and maven creates a fresh and deployble EAR file. But when I visit the applications default page the following nested exception is thrown: The MyUserServiceBean bean class for the MyApplication#MyUserServiceEjb.jar#MyUserServiceBean bean does not have a public constructor that does not take parameters.
I currently can not imagine why this exception is thrown by WL17. The feature configuration of my WL looks like this:
<featureManager>
<feature>appSecurity-2.0</feature>
<feature>cdi-1.2</feature>
<feature>distributedMap-1.0</feature>
<feature>ejbLite-3.2</feature>
<feature>ejb-3.2</feature>
<feature>jacc-1.5</feature>
<feature>jaxrs-2.0</feature>
<feature>jaxws-2.2</feature>
<feature>jca-1.7</feature>
<feature>jdbc-4.1</feature>
<feature>jndi-1.0</feature>
<feature>jpa-2.1</feature>
<feature>jsf-2.2</feature>
<feature>jsp-2.3</feature>
<feature>ldapRegistry-3.0</feature>
<feature>mdb-3.2</feature>
<feature>servlet-3.1</feature>
<feature>ssl-1.0</feature>
<feature>webCache-1.0</feature>
<feature>wmqJmsClient-2.0</feature>
</featureManager>
I is the same when I do not load the mdb or the ejb feature. Is there any idea how to solve this problem? I have googled a lot and reade half of the internet but didn't get an answer or an idea how to solve this problem.
I found the problem of the EJB. One of the interface methods was declared to throw a javax.xml.rpc.ServiceException. I do not understand why this should be a problem, but after removing the throws declaration in the interface and the implementation class WL 17 was able to initialize the bean correctly.

EJB - NullpointerException while injecting bean

I am a newbie for EJB and CDI.
Please help me understand what I am doing wrong here:
My code is as below and deployed in a WAR on JBoss WildFly 8:
#Stateless(name = "application.listDao")
public class ListDao extends BaseDao {
#Inject
private SomeOtherDao someOtherDao;
// some other methods
}
#Stateless
public abstract class BaseDao {
#Inject
protected EntityManager entityManager;
public List find( long id ) {
List list = new ArrayList<>();
// JPA stuff to perform operations
return list;
}
}
Now, I am injecting this ListDao in other WAR deployed on same wildfly instance:
#RequestScoped
public class ListReport {
#Inject
private ListDao listDao;
public List getReport(long id) {
// Here I am getting NullPointerException
List reportList = listDao.find(id);
return reportList;
}
}
I am getting listDao as null and hence getting NullPointerException.
CDI is enabled by placing empty beans.xml under WEB-INF folder.
As mentioned in one of the comments, you're #Inject'ing your EntityManager, however you haven't provided any evidence that you have a producer for it. There is no default producer method for EntityManager
If the other war is not in the same EAR (enterprise archive), this is not possible. Those are two completely separate deployments. The two deployments can't even see the classes of each other because of the classloader isolation.
You'd need to package the two wars into one ear in this case.

EJB 3.1 problems

I try to deploy a jboss5 bean project bundle on a jboss7 server. An other developer already made some changes that the code can work on jboss7, like to place a jboss-deployment-structure.xml into the project.
I created two beans, one in project A (BeanA) and one in project B (BeanB).
BeanA has to lookup for BeanB. I always get "No EJB found with interface of type 'de.foo.soa.foobar.al.BeanB' for binding de.foo.soa.foobar.ba.ProjectB/BeanB.
Bean B:
import javax.ejb.Stateless;
import javax.ejb.LocalBean;
#Stateless
#LocalBean
public class NumSrvLocalBean {
public String testNumSrv() {
return "numsrv works";
}
}
Bean A does:
#EJB private NumSrvLocalBean numSrvLocalBean;
private String numSrvLocalBean_path = "java:module/NumSrvLocalBean!de.foo.soa.foobar.al.NumSrvLocalBean";
ctx = new InitialContext();
numSrvLocalBean = (NumSrvLocalBean) ctx.lookup(numSrvLocalBean_path);
I also added the right dependency to the jboss-deployment-structure.xml:
<module name="deployment.ProjectB.jar" export="true"/>
So evertything is fine for my understanding but I always get this exception. I created my own project, lets call it project X. There I can lookup for any Bean I want to from all other projects (about 15). I cant inject in project A any bean outside from project A. But I can inject beans inside the project. So there must be something that blocks the beans inside the project.
I've got this files in project A:
jboss.xml
jboss-deployment-structure.xml
MANIFEST.MF (standard, not filled)
persistence.xml
seam.properties
ProjectA.properties (contains an wsdlUrl because this project was also configured as XML-RPC project)
I look forward four your ideas,
greetings.
I solved this problem by using EJB(mappedName="java:global/....").
I already tried EJB(mappedName=className.JNDI_NAME) but this didnt worked. We used Interfaces in JBoss 5, where we defined the JNDI name like
#Local
public interface ClassNameLocal extends ClassNameInterface {
/** Name im JNDI (Java Naming and Directory Interface) */
public final static String JNDI_NAME = "foo/bar/and/so/on/ClassName/local";
}
This seems not to work anymore. I needed to use the full path.

Vetoing a CDI bean for web-app context only

I am running an EAR module on Glassfish 3.1.2.2 and am experiencing an issue where Deltaspike is creating two instances of a bean (one in the ejb module and one in the web module).
I would like to veto this bean in the web module
public class VetoAnnotatedTypeExtension implements Extension {
public <T> void processAnnotatedType(#Observes ProcessAnnotatedType<T> type) {
if (something?) {
type.veto();
}
}
}
Is there a predicate for the something? that I can use to veto when in the web-app context?
Ears always get tricky. You could check the classloader of the class and see where it's coming from. That's probably the only reliable thing you could do.

Startup scheduler after compleate deploying

I have webproject on Java EE 5 and Websphere 7.0
I need to create scheduler and start it after deploy application.
What I tried:
I create EJB with interface:
#Local
public interface ISchedulerBean {
public void executeTimer(Timer timer);
public void createTimer();
}
stateless session bean implements this interface. Method createTimer creates timer instance from TimerService. This part of code work fine.
Also I need to call method createTimer() after application deploy.
I tried:
Add listener servletContext:
public class SchedulerInitialiserContextListener implements ServletContextListener {
//service to lookup ejb
private WebServiceLocator webServiceLocator;
private SchedulerService schedulerService;
public SchedulerInitialiserContextListener() {
webServiceLocator = new WebServiceLocator();
schedulerService = webServiceLocator.getSchedulerService();
}
public void contextDestroyed(ServletContextEvent ctx) {
}
public void contextInitialized(ServletContextEvent ctx) {
schedulerService.createTimer();
}
}
create Servlet with 1 where inject SchedulerBean in init() method and call createTimer.
But this does not work, because at first webspere deploy web application, call listeners, initialize servlets, and only then deploy ejb.jar in which all ejb are located. I can see that in webshpere log file. So when I try get ejb throw #EJB annotation or lookup I get Exception, beacause ejb has not been found.
May be is other approach to start timer after deploy ejb module or change deploy order?
You can set the startup order of your modules.
Assuming you develop with Rational Application Developer do the following:
Right click your ear project and click Java EE -> Open WebSphere Application Server Deployment.
Look for the Application section, you will see all the modules and you can set the Start weight for each one.
Make sure your web project containing the Context Listener has the largest value an you should be fine.
This operation creates an ibmconfig directory under your ear project's META-INF, make sure you package it in your build process

Categories