I am making caching solution for a method located in a servlet.
Servlet looks like following:
public class DataOptimizedServlet extends DataServlet {
...
#Override
#Cacheable(value = "dataOptimized", key = "#req.getRequestURI()")
public byte[] getData(HttpServletRequest req) {
// data retrieval logic
}
...
}
in ehcache.xml I have following configuration:
<cache alias="dataOptimized">
<expiry>
<ttl unit="hours">30</ttl>
</expiry>
<resources>
<heap unit="entries">20000</heap>
<offheap unit="MB">200</offheap>
</resources>
</cache>
Also in ctx-cache.xml file is following configuration (and this file is imported in web.xml):
<cache:annotation-driven cache-manager="ehCacheManager" />
<bean id="ehCacheManager" class="org.springframework.cache.jcache.JCacheCacheManager">
<property name="cacheManager">
<bean class="org.springframework.cache.jcache.JCacheManagerFactoryBean" p:cacheManagerUri="classpath:ehcache.xml" />
</property>
</bean>
But it does not work, method getData still gets hit for the same URLs. I have many #Cacheables working in a project and configured in the same manner, but none is in servlet directly (they're in services).
What am I missing?
are you using Spring?
IF yes, consider that spring documentation spring doc says:
"When using proxies, you should apply the #Cache* annotations only to methods with public visibility. If you do annotate protected, private or package-visible methods with these annotations, no error is raised, but the annotated method does not exhibit the configured caching settings. Consider the use of AspectJ (see below) if you need to annotate non-public methods as it changes the bytecode itself."
So you should change your method visibility to protected to public
Related
I'm porting a large Spring 3.0 application to Spring 3.2 (yes, I know). The application combines XML and annotation configuration to define routes, for example:
servlet.xml:
<context:annotation-config/>
<context:component-scan base-package="foo.bar" />
...
<mvc:annotation-driven />
...
<bean id="urlMapping" class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
...
<property name="mappings">
<props>
<prop key="/booking/default.htm">booking.default</prop>
...
</props>
</property>
...
</bean>
<bean id="booking.default" class="foo.bar.BookingController">
...
</bean>
BookingController.java
#Controller
public class BookingController {
...
#RequestMapping(method = RequestMethod.GET)
public String handleRequest(...)
...
}
In Spring 3.0, the effect is to map GET /booking/default.htm to the handleRequest method of BookingController, however I have been unable to recreate this behaviour in Spring 3.2.
Spring 3.2, it seems, ignores the XML and views every method annotated with #RequestMapping(method = RequestMethod.GET) as the same, aborting on startup with java.lang.IllegalStateException: Ambiguous mapping found.
There are a large number of methods configured this way. Some of them have the #RequestMapping in a base library class that I can't change.
I can work around it by moving the url path from the XML configuration to the annotation, but I'd like to avoid that (for various reasons) and replicate the Spring 3.0 behaviour.
Is that possible? Searching for an answer has not been successful.
UPDATE:
TL;DR: This is not possible from Spring 3.1 onwards
Reading a SO "related questions" link:
SpringMVC 3.0 to 3.1 migration of ControllerClassNameHandlerMapping
Led me to:
http://docs.spring.io/spring/docs/3.2.x/spring-framework-reference/html/mvc.html
Which contains the excerpt:
New Support Classes for #RequestMapping methods in Spring MVC 3.1
...
There are also several things no longer possible:
Select a controller first with a SimpleUrlHandlerMapping or
BeanNameUrlHandlerMapping and then narrow the method based on
#RequestMapping annotations.
Which explains my problem.
I am working on a Spring-MVC application in which I want to use #Async at-least for the methods which are fire-and-forget. When I try to use #Async and I have used #EnableAsync annotation too for class, the actions inside the method are not performed. When I add task executor in servlet-context.xml, then I get an error bean is getting currently created. I am new to Async, can anyone tell me how I can use it.
I am not using Eager loading btw.
Error log :
Caused by: org.springframework.beans.factory.BeanCurrentlyInCreationException: Error creating bean with name 'groupNotesService': Bean with name 'groupNotesService' has been injected into other beans [mattachService] in its raw version as part of a circular reference, but has eventually been wrapped. This means that said other beans do not use the final version of the bean. This is often the result of over-eager type matching - consider using 'getBeanNamesOfType' with the 'allowEagerInit' flag turned off, for example.
Code :
GroupNotesServiceImpl :
#Service
#Transactional
#EnableAsync
public class GroupNotesServiceImpl implements GroupNotesService {
#Override
#Async
public void editGroupNote(GroupNotes mnotes, int msectionId) {
//Code to be executed, which is not getting executed
}
}
Servlet-context.xml :
<task:annotation-driven executor="executor" />
<task:executor id="executor" pool-size="20"/>
<mvc:annotation-driven />
<mvc:default-servlet-handler />
<resources mapping="/resources/" location="/resources/" />
If I remove any of the mvc lines above, I get a servlet.init() threw load exception error.
Also, Is it possible to use Async where I am returning int? I checked out the Future tag, but I don't know what modifications are required.
Here is the method that returns int.
#Override
public int saveGroupNoteAndReturnId(GroupNotes mnotes, int msectionid) {
// saves note and returns its id.
}
MattachService bean :
<beans:bean id="mattachDAO"
class="com.journaldev.spring.dao.GroupAttachmentsDAOImpl">
<beans:property name="sessionFactory"
ref="hibernate4AnnotatedSessionFactory" />
</beans:bean>
<beans:bean id="mattachService"
class="com.journaldev.spring.service.GroupAttachmentsServiceImpl">
<beans:property name="groupAttachmentsDAO" ref="mattachDAO" />
</beans:bean>
Edit
I checked out that there is a problem to run #Transactional and #Async both in one class. Jira SPR-7147. The workaround suggested there was to introduce a normal facade, and I really don't know what that means.
#EnableAsync should be in configuration, not the service itself. Since you seem to use xml configuration, check this https://stackoverflow.com/a/20127051/562721. It recommends to declare org.springframework.scheduling.annotation.AsyncAnnotationBeanPostProcessor to take care of #Async annotations
I am using the HDIV Web Application Security Framework for a java web application. Every new web-page-request generates hdiv-internal security information that is cached and used for security checks.
I have the following szenario:
I have one order page that pops up a confirmation-page for 2 seconds when something was added to or removed from the cart.
after 50 popups the the underlaying order page is removed from the cache and therefor an error occurs in the app.
does anybody know how to influence the hdiv cache-removal strategy to keep the basepage alive?
One way around is to increase org.hdiv.session.StateCache.maxSize from 50 to 500.
but this would only cure the symptoms not the underlying cause.
Update:
using #rbelasko solution
I succeded to use the original org.hdiv.session.StateCache to change the maxSize to 20 and verified in the debug-log that the cachentries are dismissed after 20 entries.
When I changed it to use my own implementation it didn-t work
Bean definition
<bean id="cache" class="com.mycompany.session.StateCacheTest" singleton="false"
init-method="init">
<property name="maxSize">
<value>20</value>
</property>
</bean>
My own class
public class StateCacheTest extends StateCache
{
private static final Log log = LogFactory.getLog(StateCacheTest.class);
public StateCacheTest()
{
log.debug("StateCache()");
}
#Override
public void setMaxSize(final int maxSize)
{
super.setMaxSize(maxSize);
if (log.isDebugEnabled())
{
log.debug("setMaxSize to " + maxSize);
}
}
}
In the debug-log were no entries from StateCacheTest
Any ideas?
Update 2:
While i was not able to load a different IStateCache implementation via spring i was able to make this error less likely using
<hdiv:config ... maxPagesPerSession="200" ... />
the bean-settings definition
<property name="maxSize">
<value>20</value>
</property>
had no effect on the cachesize in my system.
You could create a custom IStateCache interface implementation.
Using the HDIV explicit configuration (not using HDIV's new custom schema) this is the default configuration for "cache" bean:
<bean id="cache" class="org.hdiv.session.StateCache" singleton="false"
init-method="init">
<property name="maxSize">
<value>200</value>
</property>
</bean>
You could create your own implementation and implement the strategy that fits your requirements.
Regards,
Roberto
First: I'm using Spring 3.0
I have a problem when configuring my controller class. The controller uses a web service which I want to define the endpoint address using a .properties file.
#Controller
public class SupportController {
#Value("#{url.webservice}")
private String wsEndpoint;
...
In my application context xml-file, I've defined this:
<context:property-placeholder location="/WEB-INF/*.properties" />
I've been reading the documentation, trying different approaches (like adding prefix systemProperties.),but I keep getting an error message telling me that it doesn't exist.
Field or property 'url' cannot be
found on object of type 'org.springframework.beans.factory.config.BeanExpressionContext'
Ok. I've figured it out.
Now, in the controller:
#Value("#{settings['url.webservice']")
Then in the context configuration I have this "helper bean":
<util:properties id="settings"
location="/WEB-INF/supportweb.properties"></util:properties>
This should work, too:
#Value("${url.webservice}")
private String wsEndpoint;
I have this configuration and it works fine:
<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="locations">
<list>
<value>classpath:application.properties</value>
</list>
</property>
</bean>
and I iniejct the property in this way
#Value("${root.log.level}")
private String prop;
the field is correctly initialized to "DEBUG" value.
you should check that the
<context:property-placeholder location="/WEB-INF/*.properties" />
is defined in webmvc-config.xml where you create instances of the #Controllers
Typically, when you declare different "<authentication-provider>" for your application (webapp in my case), Spring Security takes care of invoking providers one after another, incase of failure. So, say I have DatabaseAuthenticationProvider and LDAPAuthenticationProvider with DatabaseAuthenticationProvider declared first in the config file, at runtime, DatabaseAuthenticationProvider is invoked first and if authentication fails, LDAPAuthentication is tried. This is cool - However, what I need is a runtime switch.
I would like to have an option of chosing between these two approaches (database based authentication / ldap based authentication) and somehow swith the implementation based on thsi global setting.
How do I do it? Is it even possible with Spring-Security?
I will leave how to inject your own custom authentication provider to the other myriad of examples from Googleland and here on StackOverflow. It looks like it has to do with marking a particular bean with the xml. But hopefully I can fill in some of the other details for you.
So you've defined the class somewhat like above and I'll add more of the details that you'll need for Spring (i.e. merge the stuff from above as well.
public class SwitchingAuthenticationProvider implements AuthenticationProvider
{
....
public List<AuthenticationProvider> getProviders() { return delegateList; }
public void setProviders(List<AuthenticationProvider> providers) {
this.delegateList = providers;
}
....
}
This will allow you to inject a host of providers using spring:
<bean id="customAuthProvider1" class=".....CustomProvider1"> ... </bean>
<bean id="customAuthProvider2" class=".....CustomProvider2"> ... </bean>
...
<bean id="customAuthProviderX" class=".....CustomProviderX"> ... </bean>
<bean id="authenticationProvider" class="....SwitchingAuthenticationProvider">
<security:custom-authentication-provider/>
<!-- using property injection (get/setProviders) in the bean class -->
<property name="providers">
<list>
<ref local="customAuthProvider1"/> <!-- Ref of 1st authenticator -->
<ref local="customAuthProvider2"/> <!-- Ref of 2nd authenticator -->
...
<ref local="customAuthProviderX"/> <!-- and so on for more -->
</list>
</property>
</bean>
In the end how you populate the providers could be any means of getting the delegator a collection of providers. How they map up to which one to use is up to you. The collection could be a named mapped, based on the current state of the delegator. It could be a list of more than one to try. It could be two properties, "get/setPrimary" and "get/setSecondary" for fail-over like functionality. Once you have the delegator injected the possibilities are up to you.
Let me know if this isn't answering your question.
How about writing a delegating AuthenticationProvider that knows how to access your runtime switch and the actual instances of Database/LDAP AuthenticationProvider.
I'm thinking of something like:
public class SwitchingAuthenticationProvider implements AuthenticationProvider
{
private List<AuthenticationProvider> delegateList;
private int selectedProvider;
#Override
public Authentication authenticate(Authentication authentication)
throws AuthenticationException
{
AuthenticationProvider delegateTo = delegateList.get(selectedProvider);
return delegateTo.authenticate(authentication);
}
....
}