Spring scheduler is running twice - spring

I have read a few posts on these issues but it did not fix the problem.
#Component
#EnableScheduling
public class NotificationScheduled {
#Scheduled(cron = "0 0/5 * * * ?")
public void email() {}
}
I tried adding spring.batch.job.enabled=false in the application property file but did not work.
I also read https://docs.spring.io/spring-framework/docs/3.0.x/reference/scheduling.html#scheduling-annotation-support-scheduled section 25.5.1
I am running scheduler for every 5 min. When scheduler is kicked of (5 is up), it calls the method twice right away. Please help as I am running out of options. Thank you
As soon as I start tomcat (8.5), I see two scheduling thread. Could it tomcat?
UPDATE - I was able to fix the by removing the following line from tomcat config/server.xml. This line was deploying my app twice. I was able to see that from tocat manager.
<Context docBase="myapp path="/myapp" reloadable="true" source="org.eclipse.jst.jee.server:myapp"/>
Thank you all for your inputs.

I was able to fix the by removing the following line from tomcat config/server.xml. This line was deploying my app twice. I was able to see that from tocat manager. <Context docBase="myapp path="/myapp" reloadable="true" source="org.eclipse.jst.jee.server:myapp"/>
Thank you all for your inputs.

Related

Running scheduler in Spring boot is spawning a process external to Spring boot application context

I am scheduling a task that runs at fixed rate in Spring boot. The function that I am using to schedule a a task is as below:
private void scheduleTask(Store store, int frequency) {
final ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1);
Runnable task = store::scan;
scheduler.scheduleAtFixedRate(task, 0, frequency, TimeUnit.MILLISECONDS);
}
This works fine but if if there is an exception at application startup, the application should exit on exception. What is happening is that I get the exception in the log and the message "Application Failed to start" but looks like the scheduler shows as still running although it looks like only the scheduled thread is still running.
Any hints on how to properly schedule an asynchronous task in a Spring boot application? I tried the #Scheduled annotation but it does not run at all.
The #Scheduled should work. Have you added the #EnabledScheduling annotation to a #Configuration or the #SpringBootApplication? The Scheduling Getting Started explains it in detail.
Regarding the scheduleTask method: What calls that? Is it started outside the Spring context? If yes then Spring won't stop it. You have to take care of the lifecycle.
You should try to use the #Scheduled as it will manage the thread pools/executors for you and most people will find it easier to understand.

LegacyCookieProcessor in standalone Tomcat and Spring Boot [duplicate]

My code is working on tomcat 8 version 8.0.33 but on 8.5.4 i get :
An invalid domain [.mydomain] was specified for this cookie.
I have found that Rfc6265CookieProcessor is introduced in tomcat 8 latest versions.
It says on official doc that this can be reverted to LegacyCookieProcessor in context.xml but i don't know how.
Please let me know how to do this.
Thanks
You can try in context.xml
<CookieProcessor className="org.apache.tomcat.util.http.LegacyCookieProcessor" />
reference:
https://tomcat.apache.org/tomcat-8.0-doc/config/cookie-processor.html
Case 1: You are using Standalone Tomcat & have access to change files in tomcat server
Please follow answer by #linzkl
Case 2: You are using Standalone Tomcat but you don't have access to change files in tomcat server
Create a new file called context.xml under src/main/webapp/META-INF folder in your application & paste the content given below
<?xml version="1.0" encoding="UTF-8"?>
<Context>
<WatchedResource>WEB-INF/web.xml</WatchedResource>
<WatchedResource>WEB-INF/tomcat-web.xml</WatchedResource>
<WatchedResource>${catalina.base}/conf/web.xml</WatchedResource>
<CookieProcessor className="org.apache.tomcat.util.http.LegacyCookieProcessor" />
</Context>
When you deploy your application in Standalone Tomcat, the context.xml file you placed under META-INF folder will override the context.xml file given in tomcat/conf/context.xml
Note: If you are following this solution, you have to do it for every single application because META-INF/context.xml is application specific
Case 3: You are using Embedded Tomcat
Create a new bean for WebServerFactoryCustomizer
#Bean
WebServerFactoryCustomizer<TomcatServletWebServerFactory> cookieProcessorCustomizer() {
return new WebServerFactoryCustomizer<TomcatServletWebServerFactory>() {
#Override
void customize(TomcatServletWebServerFactory tomcatServletWebServerFactory) {
tomcatServletWebServerFactory.addContextCustomizers(new TomcatContextCustomizer() {
#Override
public void customize(Context context) {
context.setCookieProcessor(new LegacyCookieProcessor());
}
});
}
};
}
Enabling the LegacyCookieProcessor which is used in previous versions of Tomcat has solved the problem in my application. As linzkl mentioned this is explained in Apache's website https://tomcat.apache.org/tomcat-8.0-doc/config/cookie-processor.html.
The reason is that the new version of Tomcat does not understand the . (dot) in front of the domain name of the Cookie being used.
Also, make sure to check this post when you are using Internet Explorer. Apparently, it's very likely to break.
You can find context.xml in the following path.
tomcat8/conf/context.xml
<?xml version="1.0" encoding="UTF-8”?>
<!-- The contents of this file will be loaded for each web application —>
<Context>
<!-- Default set of monitored resources. If one of these changes, the -->
<!-- web application will be reloaded. -->
<WatchedResource>WEB-INF/web.xml</WatchedResource>
<WatchedResource>${catalina.base}/conf/web.xml</WatchedResource>
<!-- Uncomment this to disable session persistence across Tomcat restarts -->
<!-- <Manager pathname="" /> -->
<CookieProcessor className="org.apache.tomcat.util.http.LegacyCookieProcessor"/>
</Context>
The problem is still with Tomcat9. Same process need to follow for Tomcat 9 to set the class.
Add the class in context.xml file.
If you are using eclipse to run the application, need to set in the context.xml file in the server folder. Refer the below screenshot for more reference.
Hope this helps someone.
SameSite issue in tomcat version < 8.5.47 has resolved
In Tomcat 8.5.47 and bellow (Tomcat 8 versions), setting CookieProcessor tag to enable same site (as given bellow) in context.xml does not work due to a bug in Tomcat.
<CookieProcessor className="org.apache.tomcat.util.http.LegacyCookieProcessor" sameSiteCookies="none" />
If you find in this situation where it is not a easy thing to upgrade tomcat immediately (which I faced recently), or if you find any other case where you just need custom processing in cookies; You can write your own CookieProcessor class to get around.
Please find a custom CookieProcessor implementation and details of it's deployment steps here.
In my case I wrote a custom CookieProcessor based on LegacyCookieProcessor source code that allows tomcat 8.5.47 to enable SameSite attribute in cookies.
As mentioned by #atul, this issue persists in Tomcat 9. It will most likely persist moving forward with all future versions of Tomcat, since this is the new standard.
Using the legacy cookie processor (by adding the line above to the context.xml file) is working well for us. However, the true 'fix' is to adjust how your cookie is formed in the first place. This will need to be done in your application, not in Tomcat.
The new cookie processor does not allow the domain to start with a . (dot). Adjusting your cookie (if possible) to start with a value other than that will fix this problem without reverting to the old, legacy cookie processor.
Also, it should be obvious, but I didn't see it mentioned above: after updating the context.xml file, you need to restart the Tomcat service for the change to take effect.
Cheers!

How to programmatically shutdown a Spring Application by itself on Tomcat

How can we shutdown or stop a Spring application by itself programmatically?
We have currently using ConfigurableApplicationContext#close(), and yes, it does close the application but not shutdown or stop the application.
From the tomcat manager, the application status still is running, so the client still can connect to the web app and get the front-end resource. Besides, all servlets seems still working and can accept the request.
The below code shows how we do currently.
#Autowired
private ConfigurableApplicationContext configurableApplicationContext;
#Scheduled(cron="0 0/5 * * * ?")
private void validateLicenseExpired()
{
try
{
LicenseUtils.isLicensingPeriodValid();
} catch (LicenseInvalidException lie) {
logger.error("\t The licensing is expired", lie);
configurableApplicationContext.close();
}
}
Any help is appreciated.
If its a boot application the you can use following link to stop the application.
Programmatically shut down Spring Boot application
Otherwise you can programmatically call the shutdown.sh like below to stop the server.
String command = "<path-to-tomcat>shutdown.sh"; // for windows use bat
Process child = Runtime.getRuntime().exec(command);
[Edit]
This thread explains about stoping application like tomcat manager
Start / stop a web application from itself?

Spring scheduler tasks causes memory leak in tomcat

I have used spring scheduler to run methods using a cron timer as shown below . The application has atleast 50 scheduler beans of the same class mentioned in bold below. We create new beans by passing configuration parameters through an xml given in the property section. But we get an error from tomcat 6.0.36 which is shown as italics text below. Is this an issue , is there any way to overcome this error. If we add a lot of scheduled tasks as given below , will this not affect the application performance?
SEVERE: The web application [/App ] created a ThreadLocal with key of type [java.lang.ThreadLocal] (value [java.lang.ThreadLocal#757fad]) and a value of type [org.mozilla.javascript.Context[]] (value [[Lorg.mozilla.javascript.Context;#18e915a]) but failed to remove it when the web application was stopped. This is very likely to create a memory leak.
<task:scheduled-tasks scheduler="myScheduler">
<task:scheduled ref="taskSchedulerClass" method="callScheduler" cron="0 0/4 * * * *"/> </task:scheduled-tasks>
<task:scheduler id="myScheduler" pool-size="10"/>
**<bean id="taskSchedulerClass" class="com.abc.efg.util.xyz">**
<property name="xmlName" value="xyz.xml" /> </bean>
Rhino's context clean up has been improved only for tomcat 7 : https://issues.apache.org/bugzilla/show_bug.cgi?id=49159 . So you will still get in tomcat6. Your error does not seem related to your scheduler.

How to configure a session timeout for Grails application?

In one of controllers in my Grails application I'm preserving a parameter value in a session variable like this:
session.myVariable = params.myValue
After that, I can access the saved value from different controllers/GSP-pages as long as I actively use the app. However, if I don't use my app for a while, even though my browser window is still open, the session variable looses it's value.
Does this happens because the session expires? I was under impression that a session lives until the browser window is still open, but apparently I was wrong.
What should I do to ensure all session variables I define in my Grails app don't expire until the browser is closed? Is there any way to set session timeout manually?
Thank you in advance for your answers!
Another option would be modifying web.xml. Prior you must call
grails install-templates
Then edit src/templates/war/web.xml and add/modify after servlet-mapping:
<session-config>
<session-timeout>60</session-timeout>
</session-config>
The value of session-timeout uses minutes as unit.
Fast forward a few years... For Grails 3.0 set the session timeout with ServerProperties in the application configuration file.
grails-app/conf/application.yml
server:
session:
timeout: 3600 #seconds
Default value: 1800 seconds (30 minutes)
Verify the timeout for the
HttpSession
from a controller using getMaxInactiveInterval():
log.println "Timeout: ${session.getMaxInactiveInterval()} seconds"
Output --> Timeout: 3600 seconds
Update: Edited configuration for changes in Grails 3.1
The current grails (2.x) have a very odd design approach to setting the session timeout. None of the prevailing ideas are great:
comment out "//session Timeout" section the within the WebxmlGrails Plugin and add "sessionConfig.sessionTimeout=" to Config.groovy
grails install-templates, remove session-timeout from web.xml, add timeout in WebXmlConfig.groovy
wait for a fix. :/
A co-worker came up with the following code that works well for me and will do until a real solution is built into grails core.
Simply add the following to the bottom of your config.groovy file and then set the appropriate timeout.
grails.war.resources = { stagingDir, args ->
def webXML = new java.io.File("${stagingDir}/WEB-INF/web.xml")
webXML.text = webXML.text.replaceFirst("<session-timeout>30</session-timeout>", "<session-timeout>90</session-timeout>")
}
My I suggest that the correct solution is to allow a single line in the Config.groovy file:
session.timeout = 90;
Cheers.
With Grails 3.1.x session-timeout is deprecated. The correct property in application.yml is:
server:
session.timeout: 7200
I could be wrong, but I'm pretty sure Grails uses the sessions associated with your application container. If you're using Tomcat, for example, you can specify the length of a session.
Tutorial for changing Tomcat session length.
here is a better working solution. go you your grails home directory and find
Example: E:\grails-2.3.8\src\war\WEB-INF\web3.0.template.xml edit the session time out value to desired values:
Example:
enter code here
90
For Grails 3 application, modifying the Application.groovy worked for me:
package foo
import grails.boot.GrailsApp
import grails.boot.config.GrailsAutoConfiguration
import org.apache.catalina.Context
import org.springframework.boot.context.embedded.EmbeddedServletContainerFactory
import org.springframework.boot.context.embedded.tomcat.TomcatContextCustomizer
import org.springframework.boot.context.embedded.tomcat.TomcatEmbeddedServletContainerFactory
import org.springframework.context.annotation.Bean
class Application extends GrailsAutoConfiguration {
static void main(String[] args) {
GrailsApp.run(Application, args)
}
#Bean
EmbeddedServletContainerFactory containerFactory() {
TomcatEmbeddedServletContainerFactory containerFactory = new TomcatEmbeddedServletContainerFactory()
containerFactory.addContextCustomizers(new TomcatContextCustomizer() {
#Override
void customize(Context context) {
int oneWeekInMinute = 7 * 24 * 60
context.setSessionTimeout(oneWeekInMinute)
}
});
return containerFactory
}
}

Resources