I am using the wildfly maven plugin to deploy my Java app to a local jboss server.
I created a class with a #Scheduleannotation like this:
#Startup
#Singleton
#Slf4j
public class ClassName {
#Schedule(hour = "*", minute = "*", second = "*/20", persistent = false)
public void method() {
// Code
log.info("some log");
}
}
Now, when deploying I get the following error:
ERROR [org.jboss.as.ejb3.timer] (EJB default - 1) WFLYEJB0020: Error invoking timeout for timer: [id=879a76e7-b06d-458c-a722-70d8f1d40bc2 timedObjectId=xx-yy-server-1.0-SNAPSHOT.xx-yy-server-1.0-SNAPSHOT.ClassName auto-timer?:true persistent?:false timerService=org.jboss.as.ejb3.timerservice.TimerServiceImpl#42cdd9a initialExpiration=null intervalDuration(in milli sec)=0 nextExpiration=Tue Oct 15 17:21:00 CEST 2019 timerState=IN_TIMEOUT info=null]: javax.ejb.EJBException: java.lang.NullPointerException
Does anyone have any idea what is causing this? I am rather new to scheduling in Java so it might be something stupid, but I could not find anything online.
Thanks!
Hello,
so as this Stackoverflow question mentioned all the Timeout restrictions apply and more than it is recommended using #Stateless EJB instead of #Singleton when you have multiple timers that will be scheduled.
The #Startup annotation is to inform the EJB container to initialize the bean at the startup, you might be misusing it.
Related
This question is about developing J2EE with NetBeans/Payara.
Since using NetBeans 11.3, deployment of my EAR-Project to payara is really slow.
Problem:
I have about 20 message driven beans in my EJB-Module and for every
single one of it the following output is written to the console
during deployment:
End point determines destination name, Res name: javax.jms.Queue, JNDI name: java:global/jms/<queuename>
descriptor name : <MDB-Name>|#]
This would be ok for me if not on every occurence of such a line it takes a few seconds before the
deployment goes on, so deployment-duration is about 120s. It should be about 10s.
Setting:
In NetBeans 8.2 and payara 4.1.x it was ok.
Then I upgraded to NetBeans 11.3 -> Slow behaviour.
Then I upgraded to payara 5.201 -> There it worked a few times like a charme, but the next day:
again, very slow deployment. I really don't have a clue why.
Running on Win 10, JDK 1.8
The Messages are pushed into the queue like:
#Stateless
public class MyMessageSource {
#Inject
JMSContext context;
#Resource(mappedName = "java:module/jms/customeredited")
private Queue customerEdited;
...
private void sendToJMSQueue(Serializable container, Queue queue) {
context.createProducer().send(queue, container);
}
}
A MDB looks like:
#JMSDestinationDefinition(name = "java:module/jms/customeredited",
interfaceName = "javax.jms.Queue",
resourceAdapter = "jmsra",
destinationName = "customeredited")
#MessageDriven(mappedName = "java:module/jms/customeredited")
public class CustomerEditedHandler implements MessageListener {
#EJB //Also tried #Inject
private SomeService ...;
public CustomerEditedHandler() {
}
#Override
public void onMessage(Message message) {
//...do things...
}
I tried some settings in the project propierties, e.g. in Build -> Compile.
I tried different configurations of the #JMSDestinationDefinition, #MessageDriven and in
MyMessageSource i found around the Internet, but nothing helped.
I also tried replacing #EJB throught #Inject.
Does anyone have any ideas or advice for me?
If you need further information, please let me know!
Regards,
Stefan
I solved the issue by myself.
If anyone cares what the problem was:
It wasn't a NetBeans, Payara or J2EE issue.
It was caused by the VPN connection to our company I used so I can do home office.
I guess that the server was doing a nice detour through the internet and back again to notice that port 7676 (JMS-Port) is running on the local machine.
Holy cow.
Now I have to find a workaround for that...
Regards,
Stefan
I am trying to work with the Timer Service with JavaEE 7 and local GlassFish 4.1.
I wrote this simple class (I saw it in some example):
#Stateless
public class Tasker {
#Schedule(second = "*", minute = "*", hour = "*")
public void executeTask() {
System.out.println("Task");
}
}
But when I deploy the project, I get that error:
java.lang.RuntimeException: EJB Timer Service is not available
...
java.lang.NoClassDefFoundError: Could not initialize class org.apache.derby.jdbc.EmbeddedDriver
I don't know why this happening.
I am very new in JavaEE and I didn't find anything helpful.
How can I make it work?
Reinstalling the GlashFish server and adding persistent = false to #Schedule solved the problem.
I have this scenario:
Enterprise Application. Runs ok. --> contains MyFacade
Client application. Runs ok.
Ejb module. Runs ok, but can't test --> contains MyClass.java
DomainLibrary. --> contains entities and remote interfaces.
I want to run test file of point 3. (ejb module). Ok, first of all I put the Enterprise Application running. On second place I run the test file of the point 3.
The problem is that the remote interface ejb contained on Enterprise Application can't be found.
Error 1: It end up with an endless loop of the following output
WARNING: AS-CDI-005 Okt 22, 2013 4:49:23 PM org.glassfish.weld.BeanDeploymentArchiveImpl handleEntry
Error 1: Solved Running JUnit Tests on embedded glassfish 4 causing WARNING: AS-CDI-005
Error 2!!!:
javax.naming.NamingException: Lookup failed for [...] (MyFacade)
Ejb module: MyClass.java
#Singleton
public class MyClass implements MyClassLocal {
#EJB(lookup = "java:global/EnterpriseApplication-ejb/MyFacade!com.mydomain.repository.MyFacadeRemote")
private MyFacadeRemote myFacade;
public MyClass() {
}
public void bussinesMethod(){
System.out.println("Hello stackOverWorld! ");
myFacade.findAll();
}
}
Test method:
#Test
public void testBusinessMethod() throws Exception {
System.out.println("businessMethod");
Map<Object, Object> properties = new HashMap<Object, Object>();
properties.put(EJBContainer.APP_NAME, "MyEjbModule");
properties.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.enterprise.naming.SerialInitContextFactory");
EJBContainer container = EJBContainer.createEJBContainer(properties);
MyClassLocal instance = (MyClassLocal)container.getContext().lookup("java:global/MyEjbModule/classes/MyClass!com.mydomain.MyClassLocal");
//EJBContainer container = javax.ejb.embeddable.EJBContainer.createEJBContainer();
//MyClassLocal instance = (MyClassLocal)container.getContext().lookup("java:global/classes/MyClass");
instance.businessMethod();
container.close();
}
You may use the same approach we did for our EJB application. You may call some of the tests 'unit tests' but they are really integration tests. Running these tests includes starting the application server first, then running the JUnit test cases and finally stopping the server. These test cases act as the client, loading the ejb remote interface, make the appropriate calls, validate the return values, etc just like your client would.
One of the problems with this is that these tests can take a while to run, depending on how many you have. It also requires the server be up and running.
I know there must be better ways, but this has worked for our project for about 10 years.
Using GlassFish 3.1.2, I try to call a Session Bean from a Netbeans platform module, and I get a null pointer exception. My problem is that I have no trace explaining how / where the NPE is generated.
The code in my Module is simply:
import ejb.MySessionRemote;
import javax.ejb.EJB;
public class TestServer {
#EJB
private static MySessionRemote mySession;
public boolean execute() {
System.out.println("result = " + mySession.getString()); //NPE here: mySession is null
return true;
}
}
The Session bean "My Session", the remote interface and the application deployed on the server side are just the ones from this tutorial: https://netbeans.org/kb/docs/javaee/entappclient.html
Any help greatly appreciated.
Note: I've checked this tutorial, without solving my issue.
If mySession is null, it was probably not injected. You can inject into managed beans (EJBs for example), because these instances are managed (created/removed) by a container, and the container does the injection for you.
You can possibly inject into a POJO, if you use CDI.
If TestServer is part of a stand-alone application for example, try to lookup the EJB using JNDI. This is what your tutorial does as well. It involves setting up the properties to get an InitialContext, and the lookup of the EJB using JNDI.
My architecture:
GlassFish Server Open Source Edition 3.1.2.2 (5)
Java EE 6
Eclipse IDE
I created a EJB Timer, which prints a log message:
#Startup
#Singleton
public class ProgrammaticalTimerEJB {
private final Logger log = Logger.getLogger(getClass().getName());
#Resource(name = "properties/mailconfig")
private Properties mailProperties;
#Resource
private TimerService timerService;
#PostConstruct
public void createProgrammaticalTimer() {
log.log(Level.INFO, "ProgrammaticalTimerEJB initialized");
ScheduleExpression everyTenSeconds = new ScheduleExpression().second("*/10").minute("*").hour("*");
timerService.createCalendarTimer(everyTenSeconds, new TimerConfig("passed message " + new Date(), false));
}
#Timeout
public void handleTimer(final Timer timer) {
log.info(new Date().toGMTString() + " Programmatical: " + mailProperties.getProperty("to"));
}
}
This class injects my custom JNDI Resource:
#Resource(name = "properties/mailconfig")
private Properties mailProperties;
Eclipse Console:
INFO: 2 Aug 2013 10:55:40 GMT Programmatical: tim.herold#mylocal.de
INFO: 2 Aug 2013 10:55:50 GMT Programmatical: tim.herold#mylocal.de
INFO: 2 Aug 2013 10:56:00 GMT Programmatical: tim.herold#mylocal.de
Glassfish settings
asadmin> get server.resources.custom-resource.properties/mailconfig.property
server.resources.custom-resource.properties/mailconfig.property.to=tim.herold#mylocal.de
Command get executed successfully.
asadmin>
Now i want to change this property value during application runtime.
Editing it via Adminconsole or Asadmin doesnt work.
Is this possible, or is there an other/better soulution?
Many thanks in advance
There is a possibility to solve your problem:
If an application uses resource injection, the GlassFish Server invokes the JNDI API, and the application is not required to do so.
Once injected the properties are not reloaded and there is no direct posibility to reload the resource by default.
However, it is also possible for an application to locate resources by making direct calls to the JNDI API.
You need to do a JNDI Lookup for your Custom Resoruce, either scheduled or everytime before using the properties. This code worked for me:
#Timeout
public void handleTimer(final Timer timer) throws IOException, NamingException {
Context initialContext = new InitialContext();
mailProperties = (Properties)initialContext.lookup("properties/mailconfig");
log.info(new Date().toGMTString() + " Programmatical: " + mailProperties.getProperty("to"));
}
According to my understanding, the mailProperties resource is injected after the EJB is instantiated by the container which only occurs one time in the lifecycle of bean.
Therefore, futures properties changes are not available to him.
An alternative could be to try to lookup the mailProperties inside #Timeout method.