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.
Related
I have a rest service that is supposed to call a function using #Scheduled. The other functions in MyService work as intended locally and in live, just not the scheduled function. Any ideas on what I am missing here that would cause it to fail only in live?
#Configuration
#EnableScheduling
#EnableAsync
#ComponentScan(basePackages = "elsewhere.yyy.yyy")
public class ApplicationConfiguration {
}
#RestController
public class MyController {
#Autowired
MyService service;
}
#Service
public class MyService {
#Async
#Scheduled(fixedRate = 30000, initialDelay = 10000)
public void myTask() {
// Do stuff...
}
}
I turned on debug logging, but am seeing no org.springframework.scheduling.* logs, my theory should be that spring just isn't seeing #Scheduled for some reason and is thus not running it, but it is working perfectly fine locally! My other theory is that #Async might be causing an unexpected interaction, but it doesn't make sense to me that it would cause the function to disappear in live only... The good(?) news is that is consistently not working in live and consistently working locally.
I'm using Spring Boot version 2.5.1
The problem was caused by an ID-10T error. //Do Stuff... early on looks for a file that may or may not be there, and short circuits as intended when the file isn't there. The file was provided and the silent short circuit in a live environment made it appear as if the scheduled task was simply never running. The issue was that I provided the file to the incorrect subdirectory, putting said file into the correct directory solved the issue.
I am building a spring web socket app and I am facing the following issue.
When I am running the app using IntelliJ everything is fine and the app starts up just fine.
When I am building the fat jar with spring boot maven plugin and starting up the app using java -jar the app is failing to start with the following error
Failed to start bean 'subProtocolWebSocketHandler'; nested exception is java.lang.IllegalArgumentException: No handlers
at org.springframework.web.socket.messaging.SubProtocolWebSocketHandler:start()
My spring web socket config looks like this
#Configuration
#EnableWebSocketMessageBroker
public class WebSocketConfig implements WebSocketMessageBrokerConfigurer {
private WebSocketMessageBrokerStats webSocketMessageBrokerStats;
#Override
public void configureMessageBroker(MessageBrokerRegistry config) {
config.enableSimpleBroker("/topic")
.setHeartbeatValue(new long []{webSocketsProperties.getClientHeartbeatsSecs() * 1000, webSocketsProperties.getServerHeartbeatsSecs() * 1000})
.setTaskScheduler(heartBeatScheduler());
config.setApplicationDestinationPrefixes("/app");
}
#Override
public void registerStompEndpoints(StompEndpointRegistry registry) {
registry.addEndpoint("/gs-guide-websocket").setAllowedOrigins("*").withSockJS();
}
#Autowired
public void setWebSocketMessageBrokerStats(WebSocketMessageBrokerStats webSocketMessageBrokerStats) {
this.webSocketMessageBrokerStats = webSocketMessageBrokerStats;
}
}
The reason why the above error is happening is because when I run the app using the jar the method
#Autowired(required = false)
public void setConfigurers(List<WebSocketMessageBrokerConfigurer> configurers) {
if (!CollectionUtils.isEmpty(configurers)) {
this.configurers.addAll(configurers);
}
}
inside DelegatingWebSocketMessageBrokerConfiguration which is supposed to autowire my WebSocketConfig is invoked after the
#Override
protected void registerStompEndpoints(StompEndpointRegistry registry) {
for (WebSocketMessageBrokerConfigurer configurer : this.configurers) {
configurer.registerStompEndpoints(registry);
}
}
in DelegatingWebSocketMessageBrokerConfiguration which is causing the no handlers error. When I am starting the app through IntelliJ this is happening in reverse and everything is fine.
Does anyone have any idea why this is happening and what might be the reason causing it?
Is there any chance that loading classpath is happening in a different order in a jar vs in IntelliJ and that confuses spring?
EDIT
My WebSocketConfig class is slightly different than what I have put above. I am autowiring WebSocketMessageBrokerStats in it with setter injection. I have updated the code above. The reason why I didn't put this in my initial question is that I thought it was insignificant. But it is not. Answer is coming below...
Thanks a lot in advance
(let me know if you want more technical details from my side)
Nick
So after playing around with my code I figured out that the issues is the injection of the WebSocketMessageBrokerStats bean. Apparently this is causing WebSocketConfig bean (which is a special type of config since it implements WebSocketMessageBrokerConfigurer) to be ready at a later stage in the Spring Context Initialisation leaving List<WebSocketMessageBrokerConfigurer> configurers empty when it is checked by the registerStompEndpoints().
So the solution was to create a second configuration class and move the WebSocketMessageBrokerStats bean and all the operations on it in the new config file.
The above is fixing the jar file and I am able to run it with java -jar, however I have no idea how IntelliJ was able to run the app successfully without the fix.
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 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.
During migration application to latest Liberty I have some problem with Timer creation. The Timer is created in the #Singleton annotated class in the initialize() method (#PostConstruct). The code is enough easy:
ScheduleExpression schedule = new ScheduleExpression();
setScheduleExpressionTime(schedule);
TimerConfig timerConfig = new TimerConfig();
timerConfig.setPersistent(false);
timerScheduled = timerService.createCalendarTimer(schedule, timerConfig);
When I deploy the application I get the exception with proposal to create datasource for my persistence Timer. I know - a timer is persistence by default and requires datasource and table to keep it's state, but I ask to create non-persistence.
I was trying to remove persistence timers support from server features (I changed Java EE 7 Full Platform features to Java™ EE 7 Web Profile, so no more ejb-3.2). And now I have exception: CNTR4019E: Persistent timers cannot be created or accessed. Persistent EJB timers are not supported by any of the features configured in the server.xml file.
So, It looks like server ignores my requirement to create non-persistence timer and always trying to create persistence. This code worked before with some old WAS (JEE6), but now I couldn't deploy it.
Someone had this problem? May be I do something wrong?
Thank you in advance.
I've tested this out locally and it works OK for me. Here is the full EJB and server.xml configuration that I've used for your comparison.
If this does not work for you, you will need to provide more details on how you are creating/submitting your timer as well as more details on server configuration.
EJB class:
#Singleton
#Startup
public class MyEJB {
#Resource
TimerService timerService;
#PostConstruct
#Timeout
public void doThing() {
System.out.println("starting EJB post-construct");
ScheduleExpression schedule = new ScheduleExpression();
schedule.second(5);
TimerConfig timerConfig = new TimerConfig();
timerConfig.setPersistent(false);
Timer timerScheduled = timerService.createCalendarTimer(schedule, timerConfig);
System.out.println("Is persistent: " + timerScheduled.isPersistent());
}
}
Server configuration:
<server>
<featureManager>
<feature>webProfile-7.0</feature>
</featureManager>
<application location="app1.war"/>
</server>
I found out the reason. It is really my fault. I missed one place with timer creation. The timerService is used twice to create timers. First time in the place which I described above and second time inside an event. And second time it looks like:
timerService.createTimer(NB_OF_MILLISECONDS_UNTIL_FIRST_START, null);
Possible for some old WAS versions this code was creating a non-persistence timer, but for now it should be changed to something like:
TimerConfig timerConfig = new TimerConfig();
timerConfig.setPersistent(false);
timer = timerService.createSingleActionTimer(NB_OF_MILLISECONDS_UNTIL_FIRST_START, timerConfig);
Be careful while creating timers. :-)
Thank you for help.