getAnnotations() is empty in ejb jar - java

Steps to reproduce:
Create ejb project. (For example: Project1)
Create annotation class (For example: Test.class):
#Retention(RetentionPolicy.RUNTIME)
public #interface Test {
}
Create a simple java project. (For example: Project2)
Add Project1 as an ejb dependency to Project2.
Create simple class (For example: TestModel) and apply #Test annotation to it:
#Test
public class TestModel {
...
}
Create ear project. (For example: Project3)
Create ejb-module in Project3. (For example: Project3-ejb)
Add Project2 as a jar dependency to Project3-ejb.
Create stateless timer in Project3-ejb:
#Stateless
#LocalBean
public class Timer {
#Schedule(minute = "*", second = "*", hour = "*")
public void myTimer() {
try {
System.out.println(TestModel.class.getAnnotations().length);
} catch (SecurityException ex) {
logger.log(Level.SEVERE, null, ex);
}
}
}
Clean, build and deploy Project3 to glassfish 3 or 4.
In server output you will see 0. Why?

I found that this problem is specific only for glassfish servers. If I deploy Project3 to Jboss server, I will see 1 in the server output. Seems, this is glassfish bug. I created ticket: https://java.net/jira/browse/GLASSFISH-20990
Also, if in step 4 add Project1 as jar dependency, I see 1 in server output.

Related

EJB java.lang.ClassCastException

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

Expose EJB as JAX-RS service

I have a problem when i want to expose my EJB Project as JAX-RS service. I've tried to find a solution many times but i've not fixed it. I've succeeded deploy my application but i didn't found my rest service in localhost:4848 => Applications => My_Application. Normally, if a rest service is deployed, there is "Launch" button.
I use glassfish4 and eclipse Java EE.
My EJB Project is like that:
Package ejb: TestSessionBean.java
Package rest: RestTest.java and RestTestApp.java
TestSessionBean.java
#Path("/peter")
#Stateless
#LocalBean
public class TestSessionBean {
public TestSessionBean() {
// TODO Auto-generated constructor stub
}
#GET
public String sayHello() {
return "Hello";
}
}
RestTest.java
#Path("/ep")
public class RestTest {
#GET
public String sayBonjour() {
return "Bonjour";
}
}
RestTestApp.java
#ApplicationPath("/test/*")
public class RestTestApp extends Application {
}
I also tried to config my project: Properties => Project Facets => enable JAX-RS (but when i clicked on "Further configuration available", i had "Type: Disable Library Configuration".
I tried localhost:8080/ejbtest/test/peter/ and localhost:8080/ejbtest/test/ep but both didn't work.
But if i create a new Dynamic Web Project all and copy all of my source files in ejbtest into this project. It works! So i think about something to do in eclipse configuration of ejb project. Any solution?
Thank you in advanced.

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.

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

#AroundInvoke in a CDI project

There are 3 projects that use CDI. Project A has an Interceptor for transaction control.
Project B uses Project A to save data in a database. When I run these unit tests, everything passes.
Project C uses Project B for integration tests. These tests fails when it finds the #AroundInvoke annotation from Interceptor.
What is going wrong? The interceptor is only in Project B beans.xml.
The exception stacktrace doesn't clear up my mind. It only show a jassist error. Debugging, I found that the problem comes from boostrap.deploybeans() inside Weld. So, I commented the #AroundInvoke in the interceptor class and everything goes fine with tests, but the insert on database. I think that happens because I removed the interceptor that creates transaction for inserts.
The code:
1) There is a project A which defines an annotation and an interceptor for this annotation. Example:
/Annotation/
#InterceptorBinding
#Retention(RetentionPolicy.RUNTIME)
#Target({ElementType.TYPE, ElementType.METHOD})
public #interface Transactional {
}
/Interceptor/
#Interceptor
#Transactional
public class TransactionalInterceptor implements Serializable {
…
#AroundInvoke
public Object intercept(InvocationContext context) throws Exception {
…
}
…
}
I think this project must have an empty /META-INF/beans.xml.
2) There is another project B that uses the interceptor from project A. Example:
public class ProjectBClass {
…
#Transactional
public void interceptorMethod() {
…
}
…
}
So I think this project must have a /META-INF/beans.xml that enables the interceptor. Example:
<beans>
<interceptors>
<class>br.com.company.projecta.TransactionalInterceptor</class>
</interceptors>
</beans>
3) Finally, there's a project C that uses the method from project B. Example:
public class ProjectCClass {
…
private ProjectBClass projectBClass;
…
public void testerMethod() {
…
this.projectBClass.interceptorMethod();
…
}
…
}
I am not sure if it must have a /META-INF/beans.xml.
4) In this same project, there is an integration test which tests the method. Example:
public class ProjectCClassTest {
…
#Test
public void test() {
ProjectCClass projectCClass = new ProjectCClass();
projectCClass.testerMethod();
…
Assert.assertEquals(…);
}
…
}
You need META-INF/beans.xml in all projects (packaged as .jar)
You should not instantiate the classes yourself. If you do, they are not CDI managed. Let CDI instantiated them. For example look here.

Categories