Best way to enable timer on Glassfish web profile - spring

I use web profile and it does not allow to use Java EE #Schedule functionality. So, I have several ways to solve the problem:
reinstall the server to use full profile. Problems: it's risky (functionality/performance) for my production and burdensome
Use other scheduling functionality like Spring. Problems: I don't know how to link Spring with JavaEE as I want to use CDI beans in my scheduler. Seam-spring module could help me (http://sfwk.org/Seam3/SpringModule) but its documentation is not available at the moment and I don't really know the status of it.
So, which is the best way to enable scheduling inside my glassfish app?
Thanks

We've had a lot of luck using the Quartz open source job scheduler within Spring on other projects so I can highly recommend it for scheduling. You can configure the scheduler to be started from a Servlet (into which CDI beans can be injected) and the scheduled job can call an EJB Stateless Session bean (into which you can also inject CDI beans).
Here are some links - hope this helps!
Initialze a Scheduler in a servlet container
Here's a great article on calling an EJB from Quartz

Ok, I managed to do this using spring module. Would be better to use embedded Scheduler J2EE functionality, but this is not included into Glassfish web profile, only to full (WTF??). As my project is in prod, I don't want to upgrade to full one, especially as there is no flexible way to do this upgrade. Only full server substitute. Very poor JavaEE....
So, first, we need to define some functionality, which will be run at schedule:
#Scope(value="application")
public class ClosePolisesTimer {
BusinessAttirbuteDAO attributeDAO;
#Scheduled(cron="0 0 0 * * *")
public void doCloseObsolete() {
// ...
}
}
Second, we should create the spring configuration file with the following configuration:
<bean id="businessAttributeDAOBean" class="org.springframework.jndi.JndiObjectFactoryBean">
<property name="jndiName" value="java:global/KaskoCalculator/BusinessAttirbuteDAO" />
</bean>
<bean id="ClosePolisesTimer" class="com.rstk.kasko.bean.service.ClosePolisesTimer">
<aop:scoped-proxy />
<property name="polisDAO" ref="polisDAOBean" />
<property name="attributeDAO" ref="businessAttributeDAOBean" />
</bean>
<task:annotation-driven scheduler="closePolisExecutor"/>
<task:scheduler id="closePolisExecutor" pool-size="1"/>
That's all. I define EJB beans and use "aop:scoped-proxy" to initialize my scheduler by them. Spring schedule is included into core spring module, so only core spring dependency is necessary

Related

Correct Scope for vaadin 8 and spring

I have a project, work with Vaadin 8.6 and Spring 5, and vaadin-spring 3.1.1
In this, there is MainUI extends UI that a bean with scope="prototype" initialized in web-application-context.xml
Problem: when we connect to project from more than one client (browser), there is only one session available.
we search and find some manuals, but we can not use it in our project
<bean id="mainUI" class="ir.fanap.fanitoring.ui.MainUI" scope="prototype">
Vaadin Spring Add-on
how can we solve this problem? we did not use annotations for beans and all beans initialized in web-application-context.xml

Getting a non Spring Boot program such as ActiveMQ to work with Spring Cloud Config

I have modified my original question slightly to better reflect my question. I have a non-Spring Boot application that I would like to have working with the Spring Cloud Config Server. I have searched around online and tried many things but it seems like the crux of my issue is that the server only works within a Spring Boot context. Although ActiveMQ is a Spring application already, it seems non-trivial to convert it to be a Spring Boot one.
I would like to have an ActiveMQ Broker that is configured from the Spring Cloud Config. My local settings within the application.properties should be replaced by those that come from the server. This works in other servers I work on, now I need it to work for my Broker Filter plugins.
I added the following to activemq.xml:
<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="locations">
<list>
<value>classpath:application.properties</value>
<value>file:${activemq.conf}/credentials.properties</value>
</list>
</property>
</bean>
NOTE: Several base packages omitted here but are similar to:
<context:component-scan base-package="org.springframework.cloud.bootstrap"/>
<!-- enables annotation based configuration -->
<context:annotation-config />
After doing so I was able to get various #Value annotations to work with settings coming from my application.properties but the whole Spring Cloud Config Server thing seems to not replace my local application.properties file settings. Other Spring Boot application I work on do so I know the server is fine.
I have added the following jars to the apache-activemq-5.12.0\lib\extra directory:
spring-aop-4.1.8.RELEASE.jar
spring-beans-4.1.8.RELEASE.jar
spring-boot-1.2.7.RELEASE.jar
spring-boot-actuator-1.2.7.RELEASE.jar
spring-boot-autoconfigure-1.2.7.RELEASE.jar
spring-boot-starter-1.2.7.RELEASE.jar
spring-boot-starter-actuator-1.2.7.RELEASE.jar
spring-boot-starter-data-mongodb-1.2.7.RELEASE.jar
spring-boot-starter-logging-1.2.7.RELEASE.jar
spring-cloud-commons-1.0.1.RELEASE.jar
spring-cloud-config-client-1.0.1.RELEASE.jar
spring-cloud-context-1.0.1.RELEASE.jar
spring-cloud-starter-1.0.1.RELEASE.jar
spring-cloud-starter-config-1.0.1.RELEASE.jar
spring-context-4.1.8.RELEASE.jar
spring-context-support-4.1.8.RELEASE.jar
spring-core-4.1.8.RELEASE.jar
spring-data-commons-1.11.0.RELEASE.jar
spring-data-mongodb-1.8.0.RELEASE.jar
spring-expression-4.1.8.RELEASE.jar
spring-jms-4.1.8.RELEASE.jar
spring-security-crypto-3.2.8.RELEASE.jar
spring-test-4.1.8.RELEASE.jar
spring-tx-4.1.8.RELEASE.jar
spring-web-4.1.8.RELEASE.jar
refreshendpoint is not necessarily initialized when the constructor is called. You need to add a method annotation with #PostConstruct (or implement InitializingBean and implement afterPropertiesSet method) in which you'll perform refreshendpoint.refresh(); , e.g:
#PostConstruct
void init() {
refreshendpoint.refresh();
}

Unit test of Spring Webflow which uses bean configuration inheritance by extending AbstractXmlFlowExecutionTests

We have upgraded Spring WebFlow from 1 to 2.4.1. Now we need to rewrite all of our Unit tests. One issue is stopping us dead in our tracks. Most of our flows still import action beans and forms, as we are still using XML configurations. In addition, all of the action beans inherit configuration via an abstract bean reference in the webflow configuration file. So we have the following bean reference in our webflowContext.xml:
<bean id="serviceInjected" abstract="true">
<property name="serviceLocator" ref="serviceLocator"/>
<property name="misAssembler" ref="misAssembler"/>
<property name="formObjectScope" value="FLOW"/>
</bean>
All of the Action beans thus inherit the serviceLocator, misAssembler and formObjectScope. When I try to unit test the flows, the tests fails because there is no "serviceInjected" bean reference. So my question is:: How can we insert bean configuration inheritance into the test before we attempt to start the flow. Using configureFlowBuilderContext will not work as this change the ApplicationContext and not the ExternalContext. I have only seen one other reference to this on the internet and that question was not answered, so here is hoping I have better luck.

How can I inject Spring parameters based on Maven profile

I would like to inject Spring environment-based values (such as URL's for dev, stage, prod) into my Spring xml, based on Maven profiles.
I see a few related questions like this on DI using Maven and this on switching environments but I am not seeing a specific example of how to inject an environment-based value based on the Maven profile.
Can someone please guide me.
It sounds like you just need to use PropertyPlaceholderConfigurer:
<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
</bean>
<bean id="greetings" class="Greeting">
<property name="message" value="${greeting}" />
</bean>
Which would inject the greeting system property into your bean. Then your Maven profiles can define system properties which would be injected.
Depending on what version of Spring you're using (although it sounds like an older one, given your XML bean definitions), I would be tempted to use the Maven profile to select a Spring profile. For example, you can define -Dspring.profiles.active=dev and put your config in application-dev.properties.

Spring transaction management and OSGi

I'm new to OSGi and I have an application that I would like to migrate to OSGi.
I've created one bundle that only consists of DAO interfaces. This bundle represents my DAO services.
I've also created a second bundle that provides implementations of the DAO interfaces using JDBC. This bundle registers one service per interface using Apache Felix Dependency Manager. This way, my services are accessible from other components.
My DAO implementation classes were annotated with the #Repository annotation for automatic classpath scanning, but now I use the OSGi service registry for service registration. Therefore, the services may be obtained by client code directly using Apache Felix Dependency Manager.
The methods of my DAO implementation classes are also annotated with the #Transactional annotation for transaction management. The issue is that the #Transactional annotations will not have any effect since the DAOs are not registered in any Spring container.
What is the right way for handling transactions when using OSGi? I don't want to use Spring programmatic transaction management.
Thanks,
Mickael
Take a look at Aries Blueprint with Aries JPA and JTA. You can configure it with blueprint like the following:
<bean id="jpaDao"
class="my.jpa.JpaDao">
<jpa:context property="em" unitname="persistence" />
<tx:transaction method="*" value="Required" />
</bean>
you'll also find a working sample at my github, the sample is at line 12 in the blueprint.xml.

Resources