In one of the projects I worked on the architect used Spring WebserviceTemplate in most of the backend services and its definition in xml config is like:
<bean id="someservice" class="org.springframework.ws.client.core.WebServiceTemplate">
<property name="messageSender">
<bean class="JmsMessageSender">
....
In this configuration, the JmsMessageSender (org.springframework.ws.transport.jms.JmsMessageSender) extends WebserviceMessageSender and its underlying infrastructure is Solace the message broker.
As I understand that the webservice is for synchronous communication, the above should be using the JMS request/response model only - there is no way to use Spring's WebserviceTemplate for JMS's asynchronous model.
Is it correct? However if we start a new project for a similar purpose, wouldn't it be better to use the more simple and elegant RestfulTemplate+Json+Jackson, as opposed to SOAP+JAXB solution as above?
Related
I'm trying to configure Apache Camel with ActiveMQ to bridge between a queue on my ActiveMQ server and a queue on a remote ActiveMQ server. So far so simple. Here is the relevant bit of my camel.xml:
<camelContext xmlns="http://camel.apache.org/schema/spring" id="camel">
<route>
<from uri="local:Request"/>
<to uri="remote:Request"/>
</route>
</camelContext>
<bean id="local" class="org.apache.activemq.camel.component.ActiveMQComponent">
<property name="brokerURL" value="tcp://localhost:61616"/>
</bean>
<bean id="remote" class="org.apache.activemq.camel.component.ActiveMQComponent">
<property name="brokerURL" value="tcp://remote:61616"/>
</bean>
I've tested this on two servers I control, and it works fine. However, the remote server I'm trying to connect to is one I don't control, and (probably due to a badly-written bespoke authorization implementation) it is exhibiting a behaviour that doesn't seem to work nicely with Camel.
The issue is this: the remote server relies on all Producer instances that connect to it being for a specified destination, whereas by default, Camel seems to create an unidentified producer (JMS reference for context). If an unidentified producer is created, this remote server simply terminates the connection.
So the question I have is this: is there a way to force Camel to not use an unidentified producer, preferably without having to modify the Camel source code?
What you describe about specified destinations sounds like the default endpoint of ProducerTemplate. I have no idea if this really creates the producer as you like, but you could give it a try.
Create a Java bean that uses a ProducerTemplate to send the messages to the remote broker. Create the ProducerTemplate with a default endpoint so that you don't need to specify the endpoint to send messages.
Then change your route to use the bean as sender
.to("bean:mySenderBean")
I'm a newbie with Spring MVC but now i've been moved to a new project which uses Spring Integration to turn in channel some service. Example in the context.xml
<int:channel id="example-channel" />
<int:service-activator input-channel="example-channel" ref="exampleServiceFacade" />
For every servicefacade i have to bind the service to a channel.
I was wandering, what if I could map the classes to be turned into channels as i could map the beans with component-scan?
<context:component-scan base-package="com.package" />
so i ended up with this tutorial which speaks about some annotation:
#IntegrationComponentScan
But i cannot understand how it's related to the xml tag service activator and channel.. So i'm quite confused. Does anyone with more experience have an idea if what i'm trying to do can be done?
I just want to scan con the classes which defines channels in integration without having to declare every class.
Thanks.
Your question is a bit unclear. Any Spring Integration custom XML tag is parsed by infrastructure and registered as beans in the application context. Like you'd do that via raw <bean>.
#ComponentScan, #Configuration, #Bean and so on are marker annotations to say application context which classes treat as beans.
So, using both techniques for application context configuration you don't lose anything and can continue to mark you class with #Service and use its bean name from <service-activator ref="">.
From other side now you can fully build Spring Integration without any XML! Please, read the mentioned doc in its entirety.
I'm parsing through some inherited code of a Java app that is deployed as a WAR file in JBOSS, and uses Spring, JMS, and HornetQ. I'm trying to figure out, for lack of a better phrase, what makes the app "go". Most of the Spring examples I've seen include an application with a main() method, which imperatively acts on the beans provided by the Spring context in some way. This application has no main(). As far as I can tell, this is what's happening:
The WAR file's web.xml uses a listener to launch Spring when the application starts in JBOSS, and passes it a config file
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:application-context.xml</param-value>
</context-param>
Spring then processes the application-context.xml file, which includes this snippet:
<bean id="jmsContainer"
class="org.springframework.jms.listener.DefaultMessageListenerContainer">
<property name="connectionFactory" ref="connectionFactory" />
<property name="destination" ref="destination" />
<property name="messageListener" ref="appListenerProxy" />
Through a couple more references in the application-context.xml, the "appListenerProxy" ultimately refers to a class in the application that implements SessionAwareMessageListener, which responds to messages on a queue.
The part that's tripping me up is that I don't see any kind of code to get the jmsContainer bean and do something with it. Is that a well-defined ID, such that the Spring framework is looking for it? And if so, is that documented somewhere (along with other IDs the framework might be looking for)? http://docs.spring.io/spring/docs/current/spring-framework-reference/html/jms.html seemed to be the closest I found, but it doesn't really specify whether that ID is just in the examples by convention, or if it's a meaningful string.
Thanks
Containers in spring are part of the framework core. The Framework will scan all the containers that implement a certain container interface, and initialize them.
This also relies on the Inversion of Control (IoC) principle.
For more information on IoC Container, check this page:
IoC Container
You don't really need to do anything with DefaultMessageListenerContainer bean, its frame work part.
The DefaultMessageListenerContainer bean establish JMS session with your JMS destination on application startup. When message are received in your destination it invokes the messageListener onMessage method- in your case appListenerProxy bean.
read here.
How to exclude beans, or packages from Spring AOP processing scope?
I encountered this, while fixing Spring Integration JMX support issue on JBoss.
As a development environment, we are using Spring 3.2.0.RELEASE, Spring Integration 2.2.0.RELEASE and Jboss AS 7.1.1.
When enabling Spring Integration JMX, you are actually creating IntegrationMBeanExporter, which extracts all Spring Integration related beans from the underlying ApplicationContext and creates appropriate managed MBeans. For assigning created MBeans to server MBeanServer required, which must be defined in ApplicationContext, which is generally done using standard MBeanServerFactoryBean, which returns platform related MBeanServer.
The problem appeared, because we were using Spring AOP for some enhanced operations, and AOP post processing mechanism was trying to process platform mbeanServer like regular bean, validating initial platform ClassLoader against internal pointcuts, which it eventually failed to do.
This seems to be similar to https://jira.springsource.org/browse/SPR-9335, but with generic specifics.
So as a solution, I prevented spring from processing mbeanServer as a part ApplicationContext :
<bean id="jmxIntegration" scope="singleton" class="org.springframework.integration.monitor.IntegrationMBeanExporter">
<property name="server" value="#{ T(org.springframework.jmx.support.JmxUtils).locateMBeanServer() }"/>
</bean>
This worked, but this seems to be of a more generic problem, with AOP.
Also interesting note is that MBeanExporter in spring also refers to JmxUtils instead of context's MBeanServer.
I'm writing web application that uses Spring MVC to bind Spring beans with REST-like channels.
I've created the configuration basic both on my previous apps (pure XML configuration) and example, which used <mvc:annotation-driven/> feature. I'm pointing a package with controllers with <context:component-scan base-package="my.package"/> in spring xml file.
It is working - in Spring 3.0.6.RELEASE. However, after upgrading to 3.1.0.RELEASE my controllers stopped to be detected and no channel was registered. Spring context contains no implementation of HelloChannel interface.
Is this a bug in this Spring version, or I'm using deprecated configuration, which stopped to be supported in newer version? I got no error or warning, simply no bean is auto-detected.
The controller interface definition looks like that:
#RequestMapping("/config") public interface ConfigChannel
And the implementation:
#Controller
public class ConfigChannelImpl implements ConfigChannel
The Spring documentation indicates that interface-based #Controllers are for proxying transactional methods. As such, you are probably using the <tx:annotation-driven /> tag. The problem you now seem to have is that Spring 3.1 introduced support for CGLIB, a runtime-based bytecode manipulator. You need to add proxy-target-class="true" to your transaction configuration and add CGLIB to your classpath.
<tx:annotation-driven proxy-target-class="true" />
From http://static.springsource.org/spring/docs/3.1.0.M1/spring-framework-reference/html/mvc.html#mvc-ann-requestmapping