Announcement Announcement Module
Collapse
No announcement yet.
Help with Spring BlazeDS configuration Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • Help with Spring BlazeDS configuration

    In the examples from Jeremy on this config setup I see this: web-application-config.xml file. Is this file taking the place of the applicationContext.xml? I'm not really sure what the purpose of this file is; as there is no real explanation on it in the docs. I have setup my Spring app. to use iBatis and I'm trying to use the BlazeDS integration to talk to my serviceImpl.I unfortunately have a gap in my understanding of how this is wired together from the perspective of the applicationContext.xml and the web.xml with this file mentioned above(web-application-config.xml). In your article here: http://blog.springsource.com/2008/12...ntegration-m1/ some of your files are unclear as to what configuration block is going where.

    Anyway I'm using JDK1.5, Spring2.5.5,BlazeDS3.2 -
    Here is my applicationContext.xml
    Code:
    <!--
    	  - Nestle primary business object (default implementation).
    		- Transaction advice gets applied through the AOP configuration below.
    		-->
    	<bean id="nestleDataService" class="com.talisen.domain.logic.NestleDataServiceImpl">
    		<property name="accountDao" ref="accountDao"/>
    		<property name="buildingDao" ref="buildingDao"/>
    		<property name="electricDao" ref="electricDao"/>
    	</bean>
    
    	<!-- Expose the nestleDataService bean foro BlazeDS remoting -->
    	<bean id="nestleService"
    		class="org.springframework.flex.messaging.remoting.FlexRemotingServiceExporter">
    		<property name="messageBroker" ref="mySpringManagedMessageBroker"/>
    		<property name="service" ref="nestleDataService"/>
    	</bean>
    	
    	<!-- Maps request paths at /messagebroker to the BlazeDS MessageBroker -->
    	<bean class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
    		<property name="mappings">
    			<value>
    				/messagebroker/*=mySpringManagedMessageBroker
    			</value>
    		</property>
    	</bean>
    	
    	<!-- Dispatches requests mapped to a MessageBroker -->
    	<bean class="org.springframework.flex.messaging.servlet.MessageBrokerHandlerAdapter"/>
    and of course the web.application-config.xml as mentioned in your post as well as the remoting-config.xml, services-config.xml and remoting-config.xml.
    Here is the web.xml-
    Code:
    <?xml version="1.0" encoding="ISO-8859-1"?>
    <web-app version="2.4" xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    		xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
    
    	<display-name>Nestle Data Service</display-name>
    
    	<description>Nestle Data Application</description>
    
    	<!--
    		- Key of the system property that should specify the root directory of this
    		- web app. Applied by WebAppRootListener or Log4jConfigListener.
    	-->
    	<context-param>
    		<param-name>webAppRootKey</param-name>
    		<param-value>nestle.root</param-value>
    	</context-param>
    
    
    	<!--
    		- Location of the Log4J config file, for initialization and refresh checks.
    		- Applied by Log4jConfigListener.
    	-->
    	<context-param>
    		<param-name>log4jConfigLocation</param-name>
    		<param-value>/WEB-INF/log4j.properties</param-value>
    	</context-param>
    
    	<!--
    		- Location of the XML file that defines the root application context.
    		- Applied by ContextLoaderServlet.
    		-
    		- Can include "/WEB-INF/dataAccessContext-local.xml" for a single-database
    		- context, or "/WEB-INF/dataAccessContext-jta.xml" for a two-database context.
    	-->
    	<context-param>
    		<param-name>contextConfigLocation</param-name>
    		<param-value>/WEB-INF/dataAccessContext-local.xml /WEB-INF/applicationContext.xml</param-value>
    		
    	</context-param>
    
    	<!--
    		- Configures Log4J for this web app.
    		- As this context specifies a context-param "log4jConfigLocation", its file path
    		- is used to load the Log4J configuration, including periodic refresh checks.
    		-
    		- Would fall back to default Log4J initialization (non-refreshing) if no special
    		- context-params are given.
    		-
    		- Exports a "web app root key", i.e. a system property that specifies the root
    		- directory of this web app, for usage in log file paths.
    		- This web app specifies "petclinic.root" (see log4j.properties file).
    	-->
    	<!-- Leave the listener commented-out if using JBoss -->
    	
    	<listener>
    		<listener-class>org.springframework.web.util.Log4jConfigListener</listener-class>
    	</listener>
    	
    
    	<!--
    		- Loads the root application context of this web app at startup,
    		- by default from "/WEB-INF/applicationContext.xml".
    		- Note that you need to fall back to Spring's ContextLoaderServlet for
    		- J2EE servers that do not follow the Servlet 2.4 initialization order.
    		-
    		- Use WebApplicationContextUtils.getWebApplicationContext(servletContext)
    		- to access it anywhere in the web application, outside of the framework.
    		-
    		- The root context is the parent of all servlet-specific contexts.
    		- This means that its beans are automatically available in these child contexts,
    		- both for getBean(name) calls and (external) bean references.
    	-->
    	<listener>
    		<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    	</listener>
    
    	<!--
    		- Spring web MVC servlet that dispatches requests to registered handlers.
    		- Has its own application context, by default defined in "{servlet-name}-servlet.xml",
    		- i.e. "petstore-servlet.xml" in this case.
    		-
    		- A web app can contain any number of such servlets.
    		- Note that this web app has a shared root application context, serving as parent
    		- of all DispatcherServlet contexts.
    	-->
    	<servlet>
    		<servlet-name>nestleDataFetcher</servlet-name>
    		<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    		<init-param>
    			<param-name>contextConfigLocation</param-name>
    			<param-value>WEB-INF/config/web-application-config.xml</param-value>
    		</init-param>
    		<load-on-startup>11</load-on-startup>
    	</servlet>
    
    	<!--
    		- Dispatcher servlet mapping for the main web user interface.
    		- Either refering to "petstore" for the Spring web MVC dispatcher,
    		- or to "action" for the Struts dispatcher.
    		-
    		- Simply comment out the "petstore" reference in favour of "action"
    		- to switch from the Spring web tier to the Struts web tier.
    	-->
    	<servlet-mapping>
    		<servlet-name>nestleDataFetcher</servlet-name>
    		
    		<url-pattern>/spring/*</url-pattern>
    	</servlet-mapping>
    
    	<welcome-file-list>
    		<welcome-file>index.jsp</welcome-file>
    	</welcome-file-list>
    	<error-page>
            <error-code>404</error-code>
            <location>/error.jsp</location>
        </error-page>
    
    
    </web-app>
    Anyway some explanation of what or how the web-application-config.xml gets called from all this or the app. knows about it would help or can I just move that logic out and put it in the applicationContext.xml?

    Thanks!

  • #2
    web-application-config.xml is the default DispatcherServlet Configuration file.

    e.g if you DispatcherServlet is named nestleDataFetcher as shown the the web-application-config.xml should be named nestleDataFetcher-servlet.xml
    If you do this and you place it under WEB-INF dir the DispatcherServlet will auto pick it up because of the matching name.

    You web.xml config would then look like

    <servlet>
    <servlet-name>nestleDataFetcher </servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherSe rvlet</servlet-class>
    <load-on-startup>1</load-on-startup>
    </servlet>

    <servlet-mapping>
    <servlet-name>admin</servlet-name>
    <url-pattern>*.htm</url-pattern>
    </servlet-mapping>


    <listener>
    <listener-class>org.springframework.web.context.ContextLoade rListener</listener-class>
    </listener>
    <context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>
    /WEB-INF/applicationContext.xml
    </param-value>
    </context-param>


    If you however name it something different from what your DispatcherServlet

    then you would reference it the the Dispatcher Configuration as you have it



    e.g.

    <servlet>
    <servlet-name>nestleDataFetcher </servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherSe rvlet</servlet-class>
    <init-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>WEB-INF/some-name-servlet.xml</param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
    </servlet>

    Comment


    • #3
      more help

      I think I read through every post, and still no luck for me..

      my web.xml
      Code:
      	<context-param>
      		<param-name>contextConfigLocation</param-name>
      		<param-value>/WEB-INF/applicationContext.xml</param-value>
      	</context-param>
      
          <context-param>
            <param-name>log4jConfigLocation</param-name>
            <param-value>/WEB-INF/classes/log4j.xml</param-value>
          </context-param> 
      	<context-param>
      		<param-name>flex.class.path</param-name>
      		<param-value>/WEB-INF/flex/hotfixes</param-value>
      	</context-param>
      	<filter>
      		<filter-name>springSecurityFilterChain</filter-name>
      		<filter-class>
      			org.springframework.web.filter.DelegatingFilterProxy
      		</filter-class>
      	</filter>
      	<filter-mapping>
      		<filter-name>springSecurityFilterChain</filter-name>
      		<url-pattern>/*</url-pattern>
      	</filter-mapping>
      	
      	<listener>
      	  <listener-class>org.springframework.web.util.Log4jConfigListener</listener-class>
      	</listener>
      	<listener>
      		<listener-class>
      			org.springframework.web.context.ContextLoaderListener
      		</listener-class>
      	</listener>
          <listener>
              <listener-class>flex.messaging.HttpFlexSession</listener-class>
          </listener>
      	
      	<!-- The front controller of this Spring Web application, responsible for handling all application requests -->
      	<servlet>
      	    <servlet-name>webapp</servlet-name>
      	    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
      	    <load-on-startup>1</load-on-startup>
      	</servlet>
      	<servlet-mapping>
          	<servlet-name>webapp</servlet-name>
          	<url-pattern>/spring/*</url-pattern>
          </servlet-mapping>
      my webapp-servlet.xml
      Code:
      	<!-- Bootstraps and exposes the BlazeDS MessageBroker -->
      	<bean id="managedMessageBroker" class="org.springframework.flex.messaging.MessageBrokerFactoryBean" />
      
      	<!-- Maps request paths at /* to the BlazeDS MessageBroker -->
      	<bean class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
      	    <property name="mappings">
      	        <value>
      	            /*=managedMessageBroker
      	        </value>
      	    </property>
      	</bean>
      	
      	<!-- Dispatches requests mapped to a MessageBroker -->
      	<bean class="org.springframework.flex.messaging.servlet.MessageBrokerHandlerAdapter"/>
      
      	<bean id="firstFlexService" class="org.springframework.flex.messaging.remoting.FlexRemotingServiceExporter">
      	    <property name="messageBroker" ref="managedMessageBroker"/>
      	    <property name="service" ref="firstService"/>
      	</bean>
      	<bean id="secondFlexService" class="org.springframework.flex.messaging.remoting.FlexRemotingServiceExporter">
      	    <property name="messageBroker" ref="managedMessageBroker"/>
      	    <property name="service" ref="secondService"/>
      	</bean>
      In application-config.xml
      just import by wild card other bean defenition files.

      services-config.xml
      Code:
      	<channels>
      	
              <channel-definition id="channel-amf" class="mx.messaging.channels.AMFChannel">
                  <endpoint url="http://{server.name}:{server.port}/{context.root}/spring/messagebroker/amf"
                            class="flex.messaging.endpoints.AMFEndpoint"/>
              </channel-definition>
      
              <channel-definition id="secure-amf" class="mx.messaging.channels.SecureAMFChannel">
                  <endpoint url="https://{server.name}:{server.port}/{context.root}/spring/messagebroker/amfsecure"
                            class="flex.messaging.endpoints.SecureAMFEndpoint"/>
                  <properties>
                      <add-no-cache-headers>false</add-no-cache-headers>
                  </properties>
              </channel-definition>
              
              <channel-definition id="polling-amf" class="mx.messaging.channels.AMFChannel">
                  <endpoint url="http://{server.name}:{server.port}/{context.root}/spring/messagebroker/amfpolling"
                            class="flex.messaging.endpoints.AMFEndpoint"/>
                  <properties>
                      <polling-enabled>true</polling-enabled>
                      <polling-interval-seconds>4</polling-interval-seconds>
                  </properties>
              </channel-definition>
      	</channels>
      for destination I'm referring to this - firstFlexService ..
      Any help is much appreciated, as the SpringFactory solution was working. Thanks

      Comment


      • #4
        Do you have a default channel configured?

        Comment


        • #5
          hi jeremy
          remoting-config.xml
          Code:
          	<adapters>
          		<adapter-definition id="java-object"
          			class="flex.messaging.services.remoting.adapters.JavaAdapter"
          			default="true" />
          	</adapters>
          
          	<default-channels>
          		<channel ref="channel-amf" />
          	</default-channels>
          I've run out of ideas, on what else I could be doing.
          code : InvokeFailed, message : [MessagingError message='Destination 'firstFlexService' either does not exist or the destination has no channels defined (and the application does not define any default channels.)']

          Comment


          • #6
            And do you have the default channel set in your services-config as well? For example:

            Code:
            <services>
            
                    <service-include file-path="remoting-config.xml" />
                    <service-include file-path="proxy-config.xml" />
                    <service-include file-path="messaging-config.xml" />        
            
                    <default-channels>
                       <channel ref="my-amf"/>
                    </default-channels>
            
            </services>

            Comment


            • #7
              thanks jeremy
              I was missing that, also I didn't realize that the spring-springmvc with 2.5.6 release, was required, but is obvious now. overall pretty awesome.

              Comment


              • #8
                Hi Jeremy,

                Originally posted by jeremyg484 View Post
                And do you have the default channel set in your services-config as well? For example:

                Code:
                <services>
                
                        <service-include file-path="remoting-config.xml" />
                        <service-include file-path="proxy-config.xml" />
                        <service-include file-path="messaging-config.xml" />        
                
                        <default-channels>
                           <channel ref="my-amf"/>
                        </default-channels>
                
                </services>
                I also stumbled over this.

                This should really be documented as it is for sure something that you don't have to do when using BlazeDS directly. Actually, it looks like a hack to me.

                Do you mind explaining why this is needed?

                Thanks,
                Dirk.

                Comment


                • #9
                  Basically, when using dynamic destinations with BlazeDS (which is what we're doing under the hood), if you don't have an application-wide default channel in services-config, then you have to explicitly set the channel on the RemoteObject on the ActionScript/MXML side.

                  More details here:
                  http://livedocs.adobe.com/blazeds/1/..._5.html#194376

                  I agree we need to make a more explicit point of this in our own docs (beyond just doing it that way in the samples) as this has come up in several threads now.

                  Comment


                  • #10
                    hey - thanks for the info!

                    Dirk.

                    Comment


                    • #11
                      Hi jeremy,

                      Thanks a lot for this tricky part of configuration. I struggled a lot to get Spring+BlazeDS working with flex client.
                      I also suggest that, we should make a explicit note for this configuration.

                      Thanks and Regards,
                      Rahul

                      Comment


                      • #12
                        I also get a similar problem, though it seems with a different root cause. I define my workflowAuditService remoting service with:
                        Code:
                        <?xml version="1.0" encoding="UTF-8"?>
                        <beans xmlns="http://www.springframework.org/schema/beans" 
                               xmlns:flex="http://www.springframework.org/schema/flex"
                               xmlns:util="http://www.springframework.org/schema/util" 
                               xmlns:p="http://www.springframework.org/schema/p" 
                               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-2.5.xsd 
                                                   http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-2.5.xsd
                                                   http://www.springframework.org/schema/flex http://www.springframework.org/schema/flex/spring-flex-1.0.xsd">
                        	
                        	<bean id="myConfigProcessor" class="com.example.MyDestinationCountingConfigProcessor" />
                        
                        	<flex:message-broker>
                        		<flex:config-processor ref="myConfigProcessor" />
                        	</flex:message-broker> 
                        
                        	<bean name="workflowAuditService"  class="miniEos.WorkflowAuditService">
                        		<flex:remoting-destination channels="my-amf"/>
                        	</bean>
                        
                        </beans>
                        my services-config.xml:
                        Code:
                        <?xml version="1.0" encoding="UTF-8"?>
                        <beans xmlns="http://www.springframework.org/schema/beans" 
                               xmlns:flex="http://www.springframework.org/schema/flex"
                               xmlns:context="http://www.springframework.org/schema/context"
                               xmlns:util="http://www.springframework.org/schema/util" 
                               xmlns:p="http://www.springframework.org/schema/p" 
                               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-2.5.xsd 
                                                   http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-2.5.xsd
                                                   http://www.springframework.org/schema/flex http://www.springframework.org/schema/flex/spring-flex-1.0.xsd
                                                   http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd">
                        	
                        	<bean id="myConfigProcessor" class="com.example.MyDestinationCountingConfigProcessor" />
                        
                        	<flex:message-broker>
                        		<flex:config-processor ref="myConfigProcessor" />
                        	</flex:message-broker> 
                        
                        	<bean name="workflowAuditService"  class="miniEos.WorkflowAuditService">
                        		<flex:remoting-destination channels="my-amf"/>
                        	</bean>
                        
                        	<bean name="workflowService"  class="miniEos.WorkflowService"/>
                        
                        </beans>
                        and the error I get on the client side:
                        Code:
                        [RPC Fault faultString="[MessagingError message='Destination 'workflowAuditService' either does not exist or the destination has no channels defined (and the application does not define any default channels.)']" faultCode="InvokeFailed" faultDetail="Couldn't establish a connection to 'workflowAuditService'"]
                        I've also added the MyDestinationCountingConfigProcessor as in http://static.springframework.org/sp...l/ch02s06.html, and that also shows 0 destinations... What else is needed to wire the workflowAuditService Remote Destination in?

                        Comment


                        • #13
                          That example is actually somewhat misleading...the destinations added by Spring won't be there yet when the ConfigProcessor runs.

                          If you've got the logging turned up to "info", you should see a log message showing whether the destination was registered successfully.

                          I would suspect the problem is that you need to define a ChannelSet on the client side.

                          Comment


                          • #14
                            Yes, I can now see the following log at the server side:
                            Code:
                            2009-05-11 09:39:22,393 INFO  [org.springframework.flex.remoting.RemotingDestinationExporter] Created remoting destination with id 'workflowAuditService'
                            2009-05-11 09:39:22,395 INFO  [org.springframework.flex.remoting.RemotingDestinationExporter] Remoting destination 'workflowAuditService' has been started started successfully.
                            However, I'm struggling to add the ChannelSet in the client. I've attempted the following, but that gets me the same error about the destination not existing or having defined no default channels:
                            Code:
                            <mx:RemoteObject id="was" destination="workflowAuditService">
                            	<mx:ChannelSet>
                            		<mx:AMFChannel id="myAmf" uri="http://localhost:8088/eos2/messagebroker/amf"/>
                            	</mx:ChannelSet>
                            </mx:RemoteObject>
                            I'm guessing the http://localhost:8088/eos2/messagebroker/amf uri is correct, as it at least gets some response (albeit an empty one) when I point my browser to it.

                            Comment


                            • #15
                              Need to see your services-config.xml to know what's going on here.

                              Comment

                              Working...
                              X