Spring scopes in embedded web app in Jetty server - spring

I configured Jetty to start web app from spring context, e.i. there are two contexts:
external context which runs Jetty
internal which is run by Spring DispatcherServlet
Here is the definition of external context:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="servletHolder" class="org.eclipse.jetty.servlet.ServletHolder">
<constructor-arg name="name" value="dispatcher"/>
<constructor-arg name="servlet" value="org.springframework.web.servlet.DispatcherServlet"/>
<property name="initParameters">
<map>
<entry key="contextConfigLocation" value="classpath:dispatcher-context.xml"/>
</map>
</property>
<property name="initOrder" value="0"/>
</bean>
<bean id="servletHandler" class="org.eclipse.jetty.servlet.ServletHandler">
<property name="servlets">
<array>
<ref bean="servletHolder"/>
</array>
</property>
<property name="servletMappings">
<list>
<bean class="org.eclipse.jetty.servlet.ServletMapping">
<property name="servletName" value="dispatcher"/>
<property name="pathSpec" value="/*"/>
</bean>
</list>
</property>
</bean>
<bean id="contextHandler" class="org.eclipse.jetty.servlet.ServletContextHandler">
<property name="contextPath" value="/spring"/>
<property name="servletHandler" ref="servletHandler"/>
</bean>
<bean class="org.eclipse.jetty.server.Server" init-method="start" destroy-method="stop">
<constructor-arg name="port" value="9999"/>
<property name="handler" ref="contextHandler"/>
</bean>
</beans>
It refers to dispatcher-context.xml which is "internal".
So far it work fine unless I need to inject beans from external context into controller's beans from internal context.
Is there any way to define bean in outer scope and inject it into controller?
It would be useful in unit-test or using this server as a part of bigger existing app.
The full code is available here: https://github.com/zjor/embedded-jetty/tree/master/spring-mvc-jetty

So far I've found a workaround, I've used a combination of Jersey with Jetty and configured everything via Spring.
Code is available here: https://github.com/zjor/embedded-jetty/tree/master/jersey-jetty

Related

How to read application.properties file , while starting Ignite from spring config file

I was trying to start a Apache Ignite from spring config xml file. The spring xml has keys that it reads from application.properties file.
I am using the following command to start Apache Ignite
apache-ignite-fabric-2.6.0-bin\bin\ignite.bat D:\workspace\<application-name>\src\main\resources\ignite.xml
I tried setting up a CLASSPATH environment variable where i have kept all the related spring and ignite jars and have also kept the application.properties file. Still its somehow now able to read the apploication.properties file.
Caused by: org.springframework.beans.factory.BeanDefinitionStoreException: Invalid bean definition with name 'ignite.cfg' defined in URL [file:/D:/workspace/<application-name>/src/main/resources/ignite.xml]: No configuration setting found for key 'zookeeper'; nested exception is com.typesafe.config.ConfigException$Missing: No configuration setting found for key 'zookeeper'
at org.springframework.beans.factory.config.PlaceholderConfigurerSupport.doProcessProperties(PlaceholderConfigurerSupport.java:223)
at org.springframework.beans.factory.config.PropertyPlaceholderConfigurer.processProperties(PropertyPlaceholderConfigurer.java:222)
at org.springframework.beans.factory.config.PropertyResourceConfigurer.postProcessBeanFactory(PropertyResourceConfigurer.java:86)
at org.springframework.context.support.PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(PostProcessorRegistrationDelegate.java:283)
at org.springframework.context.support.PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(PostProcessorRegistrationDelegate.java:163)
at org.springframework.context.support.AbstractApplicationContext.invokeBeanFactoryPostProcessors(AbstractApplicationContext.java:687)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:525)
at org.apache.ignite.internal.util.spring.IgniteSpringHelperImpl.applicationContext(IgniteSpringHelperImpl.java:381)
I have tried setting the classpath as well as tried keeping the file/jar in lib directory of IGNITE_HOME directory.
ignite.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:util="http://www.springframework.org/schema/util"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/util
http://www.springframework.org/schema/util/spring-util.xsd">
<bean id="ignite.cfg" class="org.apache.ignite.configuration.IgniteConfiguration">
<!--<property name="gridLogger">
<bean class="org.apache.ignite.logger.slf4j.Slf4jLogger"/>
</property>-->
<!-- Enabling Apache Ignite native persistence. -->
<property name="peerClassLoadingEnabled" value="false"/>
<property name="dataStorageConfiguration">
<bean class="org.apache.ignite.configuration.DataStorageConfiguration">
<property name="walMode" value="NONE"/>
<property name="walArchivePath" value="D:\work\TIWorkspace\ignite\wal\archive"/>
<property name="defaultDataRegionConfiguration">
<bean class="org.apache.ignite.configuration.DataRegionConfiguration">
<property name="persistenceEnabled" value="true"/>
<!-- Increasing the buffer size to 1 GB. -->
<property name="checkpointPageBufferSize"
value="#{1024L * 1024 * 1024}"/>
</bean>
</property>
</bean>
</property>
<property name="binaryConfiguration">
<bean class="org.apache.ignite.configuration.BinaryConfiguration">
<property name="compactFooter" value="false"/>
<property name="idMapper">
<bean class="org.apache.ignite.binary.BinaryBasicIdMapper">
<property name="lowerCase" value="true"/>
</bean>
</property>
<property name="nameMapper">
<bean class="org.apache.ignite.binary.BinaryBasicNameMapper">
<property name="simpleName" value="true"/>
</bean>
</property>
</bean>
</property>
<property name="discoverySpi">
<bean class="org.apache.ignite.spi.discovery.zk.ZookeeperDiscoverySpi">
<property name="zkConnectionString" value="localhost:2181"/>
<!--<property name="zkConnectionString" value="${zookeeper.server}"/>-->
<property name="zkRootPath" value="/dbobjects"/>
</bean>
</property>
</bean>
<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="location">
<value>classpath:application.properties</value>
</property>
</bean>
Any leads could be helpful.
Thanks in advance.
The most straightforward way to achieve that is to use file-based resource URL. This one worked for me:
<bean id="placeholderConfig" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="locations">
<list>
<value>file:${IGNITE_HOME}/libs/application.properties</value>
</list>
</property>
</bean>

Apache Ignite failing to start GridManagerAdapter in Windows

I have downloaded the 2.7.5 binary and trying to run an Ignite node in Windows. These are the errors I am getting (in brief):
Failed to start manager: GridManagerAdapter
Failed to start SPI: TcpDiscoverySpi
Local node and remote node have different version numbers
This is my config file.
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="ignite.cfg" class="org.apache.ignite.configuration.IgniteConfiguration">
<property name="cacheConfiguration">
<list>
<bean class="org.apache.ignite.configuration.CacheConfiguration">
<property name="name" value="TestCache"/>
<property name="atomicityMode" value="ATOMIC"/>
<property name="backups" value="1"/>
</bean>
</list>
</property>
<!-- Enabling Apache Ignite Persistent Store. -->
<property name="dataStorageConfiguration">
<bean class="org.apache.ignite.configuration.DataStorageConfiguration">
<property name="defaultDataRegionConfiguration">
<bean class="org.apache.ignite.configuration.DataRegionConfiguration">
<property name="persistenceEnabled" value="true"/>
<property name="metricsEnabled" value="true"/>
</bean>
</property>
</bean>
</property>
<property name="discoverySpi">
<bean class="org.apache.ignite.spi.discovery.tcp.TcpDiscoverySpi">
<property name="ipFinder">
<bean class="org.apache.ignite.spi.discovery.tcp.ipfinder.multicast.TcpDiscoveryMulticastIpFinder">
<property name="addresses">
<list>
<value>127.0.0.1:47500..47509</value>
</list>
</property>
</bean>
</property>
</bean>
</property>
</bean>
</beans>
What is the solution to this?
All server and thick-clients need to be on the same version of Ignite. (There are commercial versions of Ignite that allow you to mix versions, but even that's really only designed for you to upgrade your cluster without downtime.)
Error is pretty clear: you can not mix nodes with different versions inside a single cluster. Most likely you already have a running 2.7.0 process somewhere, probably inside another machine.
First, try replace TcpDiscoveryMulticastIpFinder with static TcpDiscoveryVmIpFinder. This will force a node to connect only to provided list of IP addresses. Whereas TcpDiscoveryMulticastIpFinder will try to scan your network for running nodes if it fails to connect from predefined address list.
Also check running JAVA Ignite processes and kill them if required.

Weblogic Deployment Unable to Resolve Local Queue

We have a spring-based application that is failing to deploy on a Weblogic 10.3 container. Upon deployment, the application attempts to look up two local JMS queues within the Weblogic container's JMS module and, when the deployment takes place, the application locates one local queue okay but not the other.
Both queues are configured exactly the same except for their names are different. Why does the application locate one queue okay but not the other???
I've checked queue names JNDI names many times over and I can't see any spelling errors or anything like that.
I have turned trace logging on and I can see that the connection factory used to look up both queues is the same, the spring JMS configuration is exactly the same for both queues yet one it finds the other it does not.
I don't know what else to check to establish what the problem might be... any ideas?
This is the error I get when it fails to look up one of the queues in the Weblogic JNDI tree:
Caused by: javax.naming.NameNotFoundException: Unable to resolve 'QUEUE_NAME'. Resolved ''; remaining name 'QUEUE_NAME'
at weblogic.jndi.internal.BasicNamingNode.newNameNotFoundException(BasicNamingNode.java:1139)
PS: Both queues have the same Subdeployment and same Targets configured.
---- edited to add artifact's Spring XML Configuration snippet below ----
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
xmlns:tx="http://www.springframework.org/schema/tx" xmlns:security="http://www.springframework.org/schema/security"
xmlns:lang="http://www.springframework.org/schema/lang"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd
http://www.springframework.org/schema/security
http://www.springframework.org/schema/security/spring-security-3.0.xsd
http://www.springframework.org/schema/lang
http://www.springframework.org/schema/lang/spring-lang-3.0.xsd">
<context:component-scan base-package="com.company.service" />
<bean id="jndiTemplate" class="org.springframework.jndi.JndiTemplate">
<property name="environment">
<props>
<prop key="java.naming.factory.initial">weblogic.jndi.WLInitialContextFactory</prop>
</props>
</property>
</bean>
<!-- this is the Message Driven POJO (MDP) -->
<bean id="messageListener" class="com.company.service.controller.ServiceJMSListener" />
<!-- this is the message listener container -->
<bean id="jmsContainer"
class="org.springframework.jms.listener.DefaultMessageListenerContainer">
<property name="connectionFactory" ref="queueConnectionFactory" />
<property name="destination" ref="inboundQueue" />
<property name="messageListener" ref="messageListener" />
<property name="concurrentConsumers" value="1" />
</bean>
<!-- JNDI Connection Factory -->
<bean id="queueConnectionFactory" class="org.springframework.jndi.JndiObjectFactoryBean">
<property name="jndiTemplate">
<ref bean="jndiTemplate" />
</property>
<property name="jndiName">
<value>SERVICE_QCF</value>
</property>
</bean>
<!-- Queue to listen to -->
<bean id="inboundQueue" class="org.springframework.jndi.JndiObjectFactoryBean">
<property name="jndiTemplate">
<ref bean="jndiTemplate" />
</property>
<property name="jndiName">
<value>QUEUE_A</value>
</property>
</bean>
<bean id="outboundQueue" class="org.springframework.jndi.JndiObjectFactoryBean">
<property name="jndiTemplate">
<ref bean="jndiTemplate" />
</property>
<property name="jndiName">
<value>QUEUE_B</value>
</property>
</bean>
<bean id="queueTemplate" class="org.springframework.jms.core.JmsTemplate">
<property name="connectionFactory">
<ref bean="queueConnectionFactory" />
</property>
<property name="destinationResolver">
<ref bean="jmsDestinationResolver" />
</property>
</bean>
<bean id="jmsDestinationResolver"
class="org.springframework.jms.support.destination.JndiDestinationResolver">
<property name="jndiTemplate">
<ref bean="jndiTemplate" />
</property>
<property name="cache">
<value>true</value>
</property>
</bean>
</beans>
Can you have a look to the JDNI tree in your running server to check if the queue is created or not, and to which jndi name it is bound to ? Use the admin console for this purpose.

using a <jee:jndi-lookup string inside an instance of PropertyPlaceholderConfigurer

Environment: Windows server 2003, Spring 3.0, Tomcat 6
How can I reference a JNDI property inside a PropertyPlaceholderConfigurer?
Specifically, I'm using JNDI to look up a java.lang.String that represents a path to
a property file needed by my webapp
<jee:jndi-lookup id="mypropsfile1" jndi-name="myPropsFile1" resource-ref="true"/>
<jee:jndi-lookup id="mypropsfile2" jndi-name="myPropsFile2" resource-ref="true"/>
<bean id="propertyConfigurer"
class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="ignoreUnresolvablePlaceholders" value="true"/>
<property name="locations">
<array>
<value>how to use mypropsfile1 here ??</value>
<value>how to use mypropsfile2 here ??</value>
</array>
</property>
</bean>
My "jee:jndi-lookup"s are working AFAIK. My problem seems to be how to reference JNDI resources
inside the tag pair
Thanks in advance!
Mark
Your approach may not work Mark, this is because PropertyPlaceHolderConfigurer is a BeanFactoryPostProcessor and gets invoked at the point when the bean definitions are created, whereas the jndi lookup happens post this stage.
I saw an older Spring forum discussion item, which has a recommendation for an approach of using a jndi lookup based properties file, which may suit your needs:
I believe you will have to do something like this . I haven't tested it but basically the setLocations method in PropertyPlaceholderConfigurer takes in an array of Resource(In our case UrlResource - http://static.springsource.org/spring/docs/2.0.x/api/org/springframework/core/io/UrlResource.html) which in turn has a constructor with the file path .
<jee:jndi-lookup id="mypropsfile1" jndi-name="myPropsFile1" default-value="file:///C:/defaultPath" resource-ref="true"/>
<jee:jndi-lookup id="mypropsfile2" jndi-name="myPropsFile2" resource-ref="true"/>
<bean id="propertyConfigurer"
class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer" depends-on="mypropsfile1,mypropsfile2">
<property name="ignoreUnresolvablePlaceholders" value="true"/>
<property name="locations">
<list>
<bean class="org.springframework.core.io.UrlResource">
<constructor-arg><ref bean="mypropsfile1"/></constructor-arg>
</bean>
<bean class="org.springframework.core.io.UrlResource">
<constructor-arg><ref bean="myPropsFile2"/></constructor-arg>
</bean>
</list>
</property>
</bean>
I am not sure if there is a tag called in spring . Check this http://static.springsource.org/spring/docs/3.0.x/spring-framework-reference/html/beans.html#beans-introduction
I do this in Spring 3 using a map as follows:
<jee:jndi-lookup id="myJndiLookup" jndi-name="com.techtrip.spring.config.myJndiLookup"></jee:jndi-lookup>
<bean id="somethingWithMap" class="com.techtrip.foo.SomethingWithMap">
<property name="propMap">
<map>
<entry key="myJndiLookup" value-ref="myJndiLookup" />
</map>
</property>
</bean>
This works fine in most cases. You may run into trouble if you use AOP or something that wraps the bean in a Proxy class even if you set eager init correctly. A solution in that case is to directly access the somethingWithMap bean from the app context when needed using:
applicationContext.getBeansOfType(type, includeNonSingletons, allowEagerInit);
*Note that this will return a Map<String, T> where you can access the bean by name.
Not exactly for a single JNDI property, this is using a Properties reference instead, obtained through JNDI:
<!-- Lookup Properties reference through JNDI -->
<jee:jndi-lookup id="config-properties" jndi-name="resources/resource-name" resource-ref="true"/>
<bean id="propertyConfigurer"
class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer" depends-on="config-properties">
<property name="ignoreUnresolvablePlaceholders" value="true"/>
<!-- Once the reference is obtained from JNDI, it can be used like any other reference -->
<property name="properties" ref="config-properties"></property>
</bean>

Load webserver context.xml using Spring

Fairly new to Spring, so I'm having some trouble with this. I'm trying to use LDAP security with Spring. I can use a properties file I created inside the webapp itself. But what I would like to do is load and read the context.xml file of the server (it has all the values I need for this and other applications).
This is what I have:
<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="ignoreUnresolvablePlaceholders" value="true"/>
</bean>
<bean 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="locations">
<list>
<value>/WEB-INF/properties/dataUploadProperties.properties</value>
<value>/WEB-INF/properties/globalProperties.properties</value>
<value>context.xml</value>
</list>
</property>
</bean>
I'm able to load and read the 2 properties files, but the context.xml is not found. Does it need to be the absolute path on the server?
Thanks
Chris
So the first thing I would recommend is to use Spring Security. It has an already build in LDAP support.
but the context.xml is not found
Normally this (reading the context.xml directly) is not the way you should go.
Instead, define some properties and or JNDI resources in the context.xml and then use them in the spring configuration.
For example:
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:jee="http://www.springframework.org/schema/jee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/jee
http://www.springframework.org/schema/jee/spring-jee-3.0.xsd">
<!-- access via jndi -->
<jee:jndi-lookup id="jndiEmailSession"
jndi-name="java:comp/env/email/session/myEmailSession" />
<!-- direct access for properties required the SERVLET contect property
place older configurer, then it works like properties from normal
property files -->
<bean class="org.springframework.web.context.support.ServletContextPropertyPlaceholderConfigurer"> <property name="locations" value="classpath*:META-INF/spring/*.properties" /> </bean>
<bean class=Demo>
<property name="someString" value="${simpleValue}" />
</bean>
</beans>
context.xml:
<Resource name="email/session/myEmailSession"
type="javax.mail.Session"
auth="Container"
password="secret"
mail.debug="false"
mail.transport.protocol="smtp"
mail.smtp.auth="true"
mail.smtp.user="test#example.com"
mail.smtp.host="mail.example.com"
mail.smtp.from="test#example.com"/>
<Parameter name="simpleValue" value="any" override="false" />

Resources