How to turn off VelocityViewResolver errors in Spring? - java

I'm using Velocity and Spring. Within Spring, I'm using the VelocityViewResolver paired with the ContentNegotiatingViewResolver. For the most part, this works great. The only problem is that the ContentNegotiatingViewResolver queries the VelocityViewResolver with many different content sets (as it should).
When the Velocity engine doesn't find the particular template, an error is produced similar to the following:
2011-02-04 13:37:15,074 ERROR [http-8080-2] VelocityEngine: ResourceManager : unable to find resource 'foo.json.vm' in any resource loader.
This is not ideal. Ideally, if a template isn't found, a warning or something similar would be produced. If a template doesn't exist for a particular content type, I don't really care... as that means that content type isn't supported through that view resolver.
Any idea on how I could suppress this error though the VelocityViewResolver, VelocityView, or ContentNegotiatingViewResolver?

So, I found that the best way to do this was to add a logger statement to my log config file specifically for the Velocity engine (Velocity and my project both use Commons logging). My logger statement looks like this:
<logger name="org.apache.velocity.app">
<level value="OFF" />
</logger>

The problem will be fixed in Spring 3.2, see SPR-8640. After this improvement you will be able to configure Velocity view resolver to check unresolved views only once.

This happens because your ContentNegotiatingViewResolver uses VelocityViewResolver. You can stop it from doing that by giving it an empty (but non-null) list of view resolvers.
<bean
class="org.springframework.web.servlet.view.ContentNegotiatingViewResolver">
...
<property name="viewResolvers">
<list />
</property>
</bean>

Related

Why do I get Referenced bean nullChannel not found?

I usually get a warning about nullChannel not being defined in STS Problems view:
Referenced bean 'nullChannel' not found
But then if I add a declaration in context file, like <int:channel id="nullChannel" /> or <int:publish-subscribe-channel id="nullChannel">, I get an:
java.lang.IllegalStateException: The bean name 'nullChannel' is reserved.
I guess that's a warning I can safely ignore, but I usually try to zero out warnings, so is there something I'm missing?
UPDATE
These are the portions involved with the warning, removing them made it disappear:
<int:header-value-router input-channel="listOfMaps" header-name="transaction_type" resolution-required="false" default-output-channel="nullChannel">
<int:mapping value="52" channel="requests52ListOfMaps"/>
</int:header-value-router>
<int:service-activator input-channel="httpRequestsSendsChannel" output-channel="nullChannel" ref="conversionController" method="enable52Delivery" />
<int:service-activator input-channel="httpRequestsDeletesChannel" output-channel="nullChannel" ref="inspector" method="inspect" />
I am not sure why it was ok for me last week (probably pilot error) but I get it now with
<int:service-activator input-channel="errorChannel" output-channel="nullChannel" expression="foo" />
and, if I flip the in/out channels, the warning changes to errorChannel - the reason we don't get a warning for the input channel is because STS presumably knows that we will create input channels on the fly if needed.
I guess STS just doesn't know about these implicit beans.
I'll ask the STS guys if we can come up with a way to give them a list of implicit beans to suppress these warnings.
If that's not possible, we could consider relaxing the rule preventing the adding of a custom nullChannel bean.

Access application properties within SpEL in Spring xml configuration

I'm trying to configure a spring bean based on an application property, my end goal is described in the following pseudo code:
if ${my.config}
<bean id="myBean" class="path.to.MyBeanImplOne" />
else
<bean id="myBean" class="path.to.MyBeanImplTwo" />
end
where my.config is a boolean property.
According to this SpEL guide, #{${my.config} ? 'path.to.MyBeanImplOne' : 'path.to.MyBeanImplTwo'} is a valid expression, so I tried the following configuration:
<bean id="myBean" class="#{${my.config} ? 'path.to.MyBeanImplOne' : 'path.to.MyBeanImplTwo'}" />
but got the following exception:
Expression parsing failed; nested exception is org.springframework.expression.spel.SpelParseException: EL1041E: After parsing a valid expression, there is still more data in the expression: 'lcurly({)'
I can't find documentation for accessing properties in SpEL expressions for xml configuration. Is this supported only in Java configuration?
I've seen a number of proposed solutions to my problem (some of which are in this question). I'd like to not use systemProperties since I feel this sort of configuration should not be specified a run arguments, and I feel the use of profiles is overkill for this particular use case.
Has someone been able to do what I've attempted successfully? Or can someone confirm whether or not the syntax I've tried to use is indeed not supported in xml configuration.
Try
class="#{'${my.config}'.equals('true') ? 'path.to.MyBeanImplOne' : 'path.to.MyBeanImplTwo'}"
EDIT
This works for me...
<bean id="foo" class="#{'${my.config}'.equals('true') ? 'java.lang.Integer' : 'java.lang.String'}">
<constructor-arg value="1" />
</bean>
You cannot use SpEL in application.properties file unfortunately.
Documentation
SpEL expressions from application property files are not processed at time of parsing these files and populating the environment. However, it is possible to write a SpEL expression in #Value. If the value of a property from an application property file is a SpEL expression, it will be evaluated when consumed through #Value.

dynamically determining polling frequency in mule

I have been struggling to find a work around to be able to dynamically read the polling frequency in mule flow. Currently I am reading that from a file using spring's Propertyplaceholder at the start up and value remains the same even if the fie is changed(as we all know)..
Since poll tag needs to be the first component in the flow, There is nothing much i could do to read the "live" file update.
Is there any way I could set the polling frequency dynamically read from a file(without requiring restart)?
For Reference:
<spring:beans>
<context:property-placeholder location="file:///C:/Users/test/config.properties" />
</spring:beans>
<flow name="querying-database-pollingFlow1" doc:name="querying-database-pollingFlow1">
<poll doc:name="Poll3e3">
<fixed-frequency-scheduler frequency="${pollinginterval}"/>
<db:select config-ref="MySQL_Configuration1" doc:name="Perform a query in MySQL">
<db:dynamic-query><![CDATA[select empId,empName from employer where status='active';]]></db:dynamic-query>
</db:select>
</poll>
....</flow>
There is absolutely no issue with <fixed-frequency-scheduler frequency="${pollinginterval}"/> as you can dynamically read polling frequency from a properties file ...
The only thing I am concern here is :- <context:property-placeholder location="file:///C:/Users/test/config.properties" />
Since you are reading from a properties file outside your classpath, better try with the following :-
<context:property-placeholder
location="file:C:/Users/test/config.properties" />
One more thing .. if you are using Spring beans for properties file use the following way :-
<spring:beans>
<spring:bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<spring:property name="locations">
<spring:list>
<spring:value>file:C:/Users/test/config.properties</spring:value>
</spring:list>
</spring:property>
</spring:bean>
</spring:beans>
The clean way using FixedFrequencyScheduler is not there. You could potentially go to the registry, fetch your flow by name, then get the MessageSource and cast it to FixedFrequencyScheduler set the new interval and stop-start, however if you take a look to the code you'll see there is no setter for it and reflexion it's just too dirty.
My first choice would probably be to leverage a quartz endpoint and then leverage the quartz abilities to expose the configuration throught jmx/rmi.
I would definitely advise against using hot deploy to solve this problem especially if you need to change the frequency often. There is a risk that this will lead to problems with permgen running out of memory.
Instead you could use a flow with a quartz endpoint that fires at a relatively low frequency. Then add a filter that only lets through the message at the required frequency.
The filter can either watch a properties file for changes or expose attributes over JMX to allow you to change the frequency. Something like this.
<spring:beans>
<spring:bean id="frequencyFilter" class="FrequencyFilter" />
</spring:beans>
<flow name="trigger-polling-every-second" doc:name="trigger-polling-every-second">
<quartz:inbound-endpoint repeatInterval="1000" doc:name="Quartz" responseTimeout="10000" jobName="poll-trigger">
<quartz:event-generator-job>
<quartz:payload>Scheduled Trigger</quartz:payload>
</quartz:event-generator-job>
</quartz:inbound-endpoint>
<filter ref="frequencyFilter" />
<vm:outbound-endpoint path="query-database" />
</flow>
<flow name="query-database">
<vm:inbound-endpoint path="query-database" />
<db:select config-ref="databaseConfig" doc:name="Perform a query in database">
<db:dynamic-query><![CDATA[select empId,empName from employer where status='active']]></db:dynamic-query>
</db:select>
<logger level="ERROR" message="#[payload]"/>
</flow>

How to combine custom BeanDefinitionParser with BeanDefinitionDecorator in Spring

I use custom namespace to simplify some framework component deployment.
Our config look more or less like:
<rf:container attribute1="id">
<property name="processors" value="5" />
</rf:container>
With number of custom mandatory attributes and set of optional properties. It is parsed into a bean definition.
It should be extended now to accept property which is represented as a bean which could either be shared or declared only for this bean.
Configuration bean definition when defined as a standalone bean is created as:
<rf:config id="queue" size="100" bytes="1M"/>
Then it can be set as a property or embedded directly inside <property> tag.
But i would like to simplify that and provide a shortcut like:
<rf:container attribute1="id">
<property name="processors" value="5" />
<rf:config size="100" bytes="1M"/>
</rf:container>
which would make configuration more expressive in many cases for me.
At the moment both tags are parsed by BeanDefinitionParser implementations. I tried to use BeanDefinitionDecorator for the same name, but it looks like I don't fully understand how to use either one or both of them.
Decorators are applied when beans are parsed standard way by DefaultBeanDefinitionDocumentReader (i.e. <bean> tag) inside, but this code is not executed when custom parser is used. In our parser implementation plain properties are parsed by manually calling parsePropertyElements() inside parse method, but invoking decorator parsing is harder because BeanDefinitionHolder is not ready at that time.
What would be the right way to ensure decorators are parsed for custom bean parsers?
Current solution explicitly searches our own tags inside and handles them, but it does look wrong to me.

Generate Spring context files from template

I have a lot of repeating beans in my context definition files where only the names are different.
So when I want definition for the beans a, b and c I have to add:
<bean id="a" class="org.project.A" />
<bean id="b" class="org.project.B" />
<bean id="c" class="org.project.C" />
<bean id="aDao" class="org.project.ADAO" />
<bean id="bDao" class="org.project.BDAO" />
<bean id="cDao" class="org.project.CDAO" />
As there are many more than 3 beans, I want something like:
bean: a,b,c
templates:
- <bean id=":bean:" class="org.project.:bean:upper:" />
- <bean id=":bean:Dao" class="org.project.:bean:upper:DAO" />
Is there already a way to do this in Spring?
And if I have to implement my own solution, how can I make Spring call this function before trying to import the generated files?
There is no such functionality in Spring. You can write a maven plugin or some other pre-processing tool that searches for beans and generates the XML file.
Or you can let the Spring do this and drop the XML definitions altogether by annotating your beans with #Service, #Repository and friends.
If you use annotation based container configuration you don't need to generate the bean definition xml elements.
In one of my projects I used Apache Velocity to generate config for an IoC framework using a template file. The template language is simple yet powerful.
You may implement it as a Java app, call it from Ant, etc.
http://velocity.apache.org/
The last time I checked (several years ago), Spring used the following (simplified) algorithm to create beans:
Read XML files to get bean definition. The beans are not created immediately. Instead, their definitions are held in some data structures that later (in step 4) will be queried to create the beans.
Spring iterates over each bean definition, and uses reflection to check if a bean's class implements the BeanFactoryPostProcessor interface.
If so, that bean is created and its postProcessBeanFactory() operation is invoked. That method is typically coded to iterate over all the bean definitions and modify some of them, for example, to replace "${property.value}" with the value of a property read from a Java properties file.
Afterwards, the remaining ("normal") beans are created according to the (possibly modified) bean definitions.
It's been several years since I last looked at Spring, but if it still operates in the same way, then it might be possible to implement a class that implements the BeanFactoryPostProcessor interface and codes postProcessBeanFactory() to append a bean's id property onto its class property.

Categories

Resources