OSGI - Not able to access Application resources loaded in a service bundle - spring-mvc

I am using OSGI with Spring MVC,details are as follows
Bundle b1-declares message source as bean. the message resource is success fully autowired in a service in bundleb1.
Entry for Message Source in xml is
<bean id="messageSource" class="org.synyx.messagesource.InitializableMessageSource">
<property name="basename" value="ApplicationResources"/>
<property name="messageProvider">
<bean class="org.synyx.messagesource.jdbc.JdbcMessageProvider">
<property name="dataSource" ref="dataSource"/>
</bean>
</property>
</bean>
Message source is exposed as a service in osgi-context.xml of bundle b1 as follows
<osgi:service interface="org.springframework.context.MessageSource" ref="messageSource"/>
To import the message resources in the WAB bundle, have made following entry in osgi-context.xml of WAB have made following entry to import the messageSource service exposed by bundle b1.
Note - i have not created messageSource bean in WAB(not defined messageSource in *-servlet.xml) as i expect the messageSource to be imported from Bundle B1 and be used by spring for lang resolution.
Problem is -when i hit sample Jsp placed in WAB
i recieve error
javax.servlet.ServletException: javax.servlet.jsp.JspTagException: No message found under code 'user.nametext' for locale 'en_US'.
Analysis- Further debugging the spring code i found that messagesource used in webapplication context is of type DelegatingMessageSource. But the messageSource imported from bundle b1 expose object of type InitializableMessageSource.
This means webapplication context is not initialized with messageSource that is imported through osgi-context.xml of WAB.
PLS help...

In your consumer bundle, add the following to your sping config:
<osgi:reference id="messageSource" interface="org.springframework.context.MessageSource" />
Then, you can inject the messageSource-bean as you would do with a local bean.

Related

Tomcat 7: BeanInitializazionException with Spring MVC and external property file

I have a web application bulit in Spring MVC that has an external property file.
The external file is defined in application-config.xml as follows:
<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="locations">
<list>
<!-- file di properties -->
<value>file:/myfolder/myfilename.properties</value>
<value>classpath:environment.properties</value>
</list>
</property>
<property name="ignoreUnresolvablePlaceholders" value="true"/>
</bean>
The file is in /myfolder and is under my C:\ folder, but I need to deploy it (in production environment) on a Linux machine in which the property file path is /myfolder.
This web application runs well in Netbeans IDE (8.2) with local Tomcat 7 instance.
I am trying to run it in Eclipse with same local Tomcat 7 instance but I obtain the following exception:
ERROR ContextLoader:319 - Context initialization failed
org.springframework.beans.factory.BeanInitializationException: Could not load properties; nested exception is java.io.FileNotFoundException: \myfolder\myfilename.properties (Impossible to find the path specified)
I've tried to change the server configuration in Eclipse, but nothing happens. How can I solve this issue?

how to understand that SpringMVC resource-chain includes resolvers that I have not set

My dispatcher.xml sets resource chain like below:
<mvc:resources location="/static/" mapping="/static/**" cache-period="31536000">
<mvc:resource-chain resource-cache="true">
<mvc:resolvers>
<!--<bean class="org.springframework.web.servlet.resource.GzipResourceResolver"/>-->
<bean class="org.springframework.web.servlet.resource.CachingResourceResolver">
<constructor-arg ref="staticResourceCache"/>
</bean>
<bean class="org.springframework.web.servlet.resource.VersionResourceResolver">
<property name="strategyMap">
<map>
<entry key="/**">
<bean class="org.springframework.web.servlet.resource.ContentVersionStrategy"/>
</entry>
</map>
</property>
</bean>
<bean class="org.springframework.web.servlet.resource.PathResourceResolver"/>
</mvc:resolvers>
<mvc:transformers>
<bean class="org.springframework.web.servlet.resource.CachingResourceTransformer">
<constructor-arg ref="staticResourceCache"/>
</bean>
<bean class="org.springframework.web.servlet.resource.CssLinkResourceTransformer">
<!--<property name="allowedLocations" value="/static"> </property>-->
</bean>
</mvc:transformers>
</mvc:resource-chain>
</mvc:resources>
when I debug the codes ,I find that the resource chains has two PathResourceResolver, why ?Thank you!
ResourceHttpRequestHanndler state
I suspect Spring is adding a default PathResourceResolver bean with the default id pathResourceResolver. You are explicitly declaring one but without an id, so you are ending up with 2.
The Spring Framework does this a lot - ie. it will create default beans for you unless you specify a bean with the same id.
You can test this theory by:
1) comment your PathResourceResolver out of your config? Do you end up with 1?
2) use your PathResourceResolver in your config, but give it the id pathResourceResolver? Do you end up with 1?
I have just find there exist note in the spring-mvc-4.3.xsd:
<xsd:documentation source="org.springframework.web.servlet.config.annotation.ResourceChainRegistration"><![CDATA[
Assists with the registration of resource resolvers and transformers.
Unless set to "false", the auto-registration adds default Resolvers (a PathResourceResolver) and Transformers
(CssLinkResourceTransformer, if a VersionResourceResolver has been manually registered).
The resource-cache attribute sets whether to cache the result of resource resolution/transformation;
setting this to "true" is recommended for production (and "false" for development).
A custom Cache can be configured if a CacheManager is provided as a bean reference
in the "cache-manager" attribute, and the cache name provided in the "cache-name" attribute.
]]></xsd:documentation>

Thymeleaf template engine swallowing exceptions

I'm using thymeleaf 2.0.5 with spring 3 mvc configured as follows in webmvc-config.xml
<bean id="templateResolver"
class="org.thymeleaf.templateresolver.ServletContextTemplateResolver"
p:prefix="/WEB-INF/templates/"
p:suffix=".html"
p:templateMode="HTML5" />
<bean id="templateEngine"
class="org.thymeleaf.spring3.SpringTemplateEngine"
p:templateResolver-ref="templateResolver" />
<bean id="viewResolver"
class="org.thymeleaf.spring3.view.ThymeleafViewResolver"
p:templateEngine-ref="templateEngine" />
The above configuration is working fine. The problem is that when an exception is thrown I see the following cryptic message in the logs:
ERROR org.thymeleaf.TemplateEngine - [THYMELEAF][1] Exception processing template "dataAccessFailure": Error resolving template "dataAccessFailure", template might not exist or might not be accessible by any of the configured Template Resolvers
Is there a way to configure the view resolver to exclude certain patterns?
As per the accepted answer I changed the following bean config in webmvc-config.xml
<bean id="viewResolver"
class="org.thymeleaf.spring3.view.ThymeleafViewResolver"
p:templateEngine-ref="templateEngine"
p:viewNames="index,questionnaires/*" />
You can configure your template resolver to only resolve certain view names by means of the template resolver's viewNames property. In this property you can enter several patterns (separated by commas) and use wildcards like e.g. admin/*.
Disclaimer, due to StackOverflow rules: I am thymeleaf's author.
Could you possibly have an error page mapped to "dataAccessFailure" in your web.xml. Something like:
<error-page>
<exception-type>java.lang.Throwable</exception-type>
<location>/dataAccessFailure</location>
</error-page>

Where does one place share beans in the extension path in alfresco?

I am trying to figure out where to place a share bean in the extension path. I have tried placing it in the following directories:
1) tomcat/shared/classes/
2) tomcat/shared/classes/alfresco/
3) tomcat/shared/classes/alfresco/web-extension
The bean has been declared in the custom-slingshot-application-context.xml along with some localized resources (the .properties files <== They get picked up). Some additional info. It's a share side bean because I can drop the package into the src directory of the expanded war file in the IDE and run share and it'll work.
Update
This is the custom-slingshot-application-context.xml content:
<beans>
<!-- Override WebScript Messages - add slingshot application messages -->
<bean id="webscripts.resources" class="org.springframework.extensions.surf.util.ResourceBundleBootstrapComponent">
<property name="resourceBundles">
<list>
<value>webscripts.messages.webscripts</value>
<value>alfresco.web-extension.messages.common</value>
<value>alfresco.web-extension.messages.slingshot</value>
<value>alfresco.web-extension.messages.profPerson</value>
</list>
</property>
</bean>
<bean id="webframework.factory.user.profPerson" class="com.test.ext.profUserFactory" parent="webframework.factory.base" />
</beans>
It seems you're using Tomcat, but as #Gagravarr mentions unless you are using the Tomcat supplied by the Alfresco installers, then the shared/classes directory is not enabled out of the box.
In Tomcat6/7, you need to add the following line to your conf/catalina.properties file (or modify it if it is already defined)
shared.loader=${catalina.base}/shared/classes,${catalina.base}/shared/lib/*.jar
More information is available on the Install Tomcat6 wiki page.

External properties loader with Tomcat server

I am trying to deploy a spring mvc webapp into a tomcat server. I have been testing locally using the maven-jetty-plugin. In my spring configuration I am using a properties placeholder, and pulling my properties from an external file:
<context:property-placeholder ignore-resource-not-found="true" ignore-unresolvable="true"/>
<bean id="modelPropertyPlaceholder" class="org.springframework.web.context.support.ServletContextPropertyPlaceholderConfigurer">
<property name="systemPropertiesModeName" value="SYSTEM_PROPERTIES_MODE_OVERRIDE"/>
<property name="searchContextAttributes" value="true"/>
<property name="contextOverride" value="true"/>
<property name="ignoreResourceNotFound" value="true"/>
<property name="ignoreUnresolvablePlaceholders" value="true"/>
<property name="locations">
<list>
<value>classpath:default.model.properties</value>
<value>file:/etc/app/app.properties</value>
<value>${config}</value>
</list>
</property>
</bean>
This worked with my jetty plugin...however when I deploy the WAR file to the tomcat server I receive the following error:
org.apache.commons.dbcp.SQLNestedException: Cannot create JDBC driver of class '' for connect URL 'null'
In my external properties file I have the driver class and connect url defined. as so:
jndi.jpa.rms.datasource=jdbc/testDS
rms.db.driver=com.mysql.jdbc.Driver
rms.db.url=jdbc:mysql://testdatabaseurl:3306/test
rms.db.user=sa
rms.db.password=asfdas
rms.db.checkconnsql=select 1
rms.hibernate.generateddl=false
rms.hibernate.showsql=true
rms.hibernate.dbdialect=org.hibernate.dialect.MySQLDialect
Update:
It seems that tomcat does pickup the external properties file:
14:23:09.803 [main] DEBUG o.s.b.f.s.DefaultListableBeanFactory - Finished creating instance of bean 'modelPropertyPlaceholder'
14:23:09.810 [main] INFO o.s.w.c.s.ServletContextPropertyPlaceholderConfigurer - Loading properties file from class path resource [default.model.properties]
14:23:09.810 [main] INFO o.s.w.c.s.ServletContextPropertyPlaceholderConfigurer - Loading properties file from URL [file:/etc/app/app.properties]
14:23:09.810 [main] INFO o.s.w.c.s.ServletContextPropertyPlaceholderConfigurer - Loading properties file from ServletContext resource [/${config}]
14:23:09.811 [main] WARN o.s.w.c.s.ServletContextPropertyPlaceholderConfigurer - Could not load properties from ServletContext resource [/${config}]: Could not open ServletContext resource [/${config}]
I'm not sure why tomcat isn't picking up the connection url and driver.
Is this a tomcat issue or am I missing something? Thanks
It's not a Tomcat issue, you must have made some minor mistake and properties are not loaded.
Are properties files located in proper place on your Tomcat environment?
Are you sure that in those properties files you have not left some keys blank?
If both answers to that questions are true, try changing your config with following:
<context:property-placeholder location="ADD_PATH_TO_YOUR_FILES SEPARATED_WITH_SPACES"/>
I guess that you are mixing here two property placeholders, one 'regular' and the other - bounded to servlet context. I can bet that somehow they get overlapped and one of them is getting silently ignored.
I would just stick to property-placeholder.
Old question, but...
Judging from the log output, it appears that Spring has not resolved your ${config} reference, or else this would have been substituted into the path given in the last log message:
Could not load properties from ServletContext resource [/${config}]: Could not open ServletContext resource [/${config}]
Here's a case I just encountered where it resolved ${catalina.home}/conf/myprops.properties correctly but was unable to load the referenced file:
Could not load properties from ServletContext resource [/D:/somepath/apache-tomcat/conf/myprops.properties]: Could not open ServletContext resource [/D:/somepath/apache-tomcat/conf/myprops.properties]
I tracked down the error in my case - I needed to prefix the external file reference with 'file:'. That is, it should have been file:${catalina.home}/conf/myprops.properties
(It is possible the Spring version difference may have impacted on the log output for you though also, and that it did resolve the reference but just did not show this in the output. For reference, I'm using Spring 4.1.6 at present).

Resources