Announcement Announcement Module
Collapse
No announcement yet.
Flex BlazeDS Spring Java Hibernate Conf - Server side calls create new java instances Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • Flex BlazeDS Spring Java Hibernate Conf - Server side calls create new java instances

    Hi,

    i'm pretty new to Spring so bear with me here.
    I've got an application configured with Flex on the client side and Java-Spring-Hibernate on the Tomcat server side.
    I've been able to set up my configuration to communicate between the Flex and Java however, the remoting calls seem to create new instances of the Java classes, hence, i cannot retrieve already instanciated global variables.
    I'm pretty sure all this stems from a wrong bean definition or something of the sort, which is what i'm not good at.

    The scenario is as follows: my JSP contains a Flex application. The JSP is associated to a Java controller class which is instanciated as soon as the JSP is displayed. During this initial instanciation, a service variable is instantiated (this service variable will enable me to call a DAO to retrieve data from the database).
    Then, following a user action, the Flex calls the Java controller class. The call arrives in the appropriate Java function, which is then supposed to use the service global variable to call a DAO and retrieve data from the database.
    Unfortunately, the service variable is null. I believe this is because the remoting call created a new instance of the Java controller class instead of using the already existing one.

    I'm pretty sure this is a pretty basic error on my part but i can't seem to find posts anywhere relating to it.

    here are my configuration files:

    web.xml
    Code:
    <web-app...>
    	<context-param>
    		<param-name>contextConfigLocation</param-name>
    		<param-value>classpath*:/META-INF/spring/applicationContext-web.xml</param-value>
    	</context-param>
    	
    	<listener>
    		<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    	</listener>
    	<listener>
    		<listener-class>com.kleegroup.core.boot.ContextLoaderListener</listener-class>
    	</listener>
    	<listener>
    		<listener-class>flex.messaging.HttpFlexSession</listener-class>
    	</listener>
    
    	<!-- Processes application requests -->
    	<servlet>
    		<servlet-name>appServlet</servlet-name>
    		
    		<servlet-class>com.kleegroup.core.managers.monitoring.CounterDispatcherServlet</servlet-class>
    		<init-param>
    			<param-name>contextConfigLocation</param-name>
    			<param-value>classpath*:/META-INF/spring/applicationContext-servlet.xml</param-value>
    		</init-param>
    		<load-on-startup>1</load-on-startup>
    	</servlet>
    
    	<servlet-mapping>
    		<servlet-name>appServlet</servlet-name>
    		<url-pattern>*.html</url-pattern>
    	</servlet-mapping>
    	
    	<servlet>
    		<servlet-name>flex</servlet-name>
    		<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    		<init-param>
    			<param-name>contextConfigLocation</param-name>
    			<param-value>/WEB-INF/flex-servlet.xml</param-value>
    		</init-param>
    		<load-on-startup>2</load-on-startup>
    	</servlet>
    	<servlet-mapping>
    		<servlet-name>flex</servlet-name>
    		<url-pattern>/messagebroker/*</url-pattern>
    	</servlet-mapping>
    
    	
    </web-app>

    application-context.xml
    Code:
    <beans...>
    	<bean id="validator"		class="org.springframework.validation.beanvalidation.LocalValidatorFactoryBean" />
    	<bean		class="org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor">
    		<property name="autowiredAnnotationType" value="javax.inject.Inject" />
    	</bean>
    
    	<!-- Enables the Spring MVC @Controller programming model -->
    	<mvc:annotation-driven />
    
    	<bean id="dataSource" class="org.springframework.jndi.JndiObjectFactoryBean">
    		<property name="jndiName">
    			<value>java:comp/env/jdbc/DataSource</value>
    		</property>
    	</bean>
    
    	<!-- Configure the multipart resolver -->
    	<bean id="multipartResolver"
    		class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
    	</bean>
    
    	<!-- Dispatches requests mapped to a MessageBroker -->
    	<bean class="org.springframework.flex.servlet.MessageBrokerHandlerAdapter" />
    
    	<import resource="applicationContext-monitoring.xml" />
    
    	<import resource="applicationContext-hibernate.xml" />
    
    	<!-- Généré -->
    	<import resource="applicationContext-domains.xml" />
    
    	<import resource="applicationContext-dao.xml" />
    
    	<import resource="applicationContext-controllers.xml" />
    	<!-- Fin Généré -->
    
    	<import resource="applicationContext-services.xml" />
    
    </beans>
    flex-servlet.xml
    Code:
    <beans ...>
    <flex:message-broker services-config-path="/WEB-INF/flex/services-config.xml">
    		<flex:remoting-service default-channels="my-amf" />
    	</flex:message-broker>
    </beans>
    and services-config.xml
    Code:
    <?xml version="1.0" encoding="UTF-8"?>
    <services-config>
        <channels>
            <channel-definition id="my-amf"
                class="mx.messaging.channels.AMFChannel">
                <endpoint 
                    class="flex.messaging.endpoints.AMFEndpoint"
                    url="http://{server.name}:{server.port}/{context.root}/messagebroker/amf"/>
            </channel-definition>
        </channels>
    
        <security>
            <login-command 
                class="flex.messaging.security.TomcatLoginCommand"
                server="Tomcat"/>
        </security>
        <services>
            <service id="remoting-service"
                class="flex.messaging.services.RemotingService">
                <adapters>
                    <adapter-definition id="java-object"
                        class="flex.messaging.services.remoting.adapters.JavaAdapter"
                        default="true"/>
                </adapters>
                <default-channels>
                    <channel ref="my-amf"/>
                </default-channels>
    
                <destination id="sampleDestination">
                    <properties>
                        <source>com.kleegroup.proto.ui.controller.flexsample.FlexSampleControllerImpl
    					</source>
    					<scope>session</scope>
                    </properties>
                </destination>
            </service>
        </services>
    </services-config>

    The Java controller class is as follows:
    Code:
    @Controller
    @RequestMapping(FlexSampleController.ADDRESS)
    public class FlexSampleControllerImpl extends AbstractController implements FlexSampleController {
    
    	@RequestMapping(method = RequestMethod.GET)
    	@ModelAttribute(AbstractFlexSampleModel.MODEL_NAME)
    	public ModelAndView initModelAndView() {
    		final FlexSampleModel model = new FlexSampleModel();
    		return forward(DEFAULT_VIEW, model);
    	}
    
    	@Inject
    	private LigneService ligneService; <- this is the service i need to use which is null when called by Flex
    
    	public final Collection<LigneBus> getLigneBusList() {
    		final Collection<LigneBus> result = ligneService.getLigneBusList();
    		return result;
    	}
    }
    The @Inject annotation on the LigneService enables it to be instantiated by Spring automatically. This is what is lost in the remoting call.

    Thanks in advance for your insight
    Best regards
    Pier

  • #2
    I see a number of different mistakes in your configuration:

    1) You do not need to explicitly define a MessageBrokerHandlerAdapter bean. Using the <flex:message-broker> tag handles that.

    2) When using Spring BlazeDS, you should not need the <security> section, nor the <services> section in services-config.xml. The explicit definition of the Controller as a RemotingDestination using the non-Spring BlazeDS configuration is the thing that is causing the Controller to be instantiated outside of Spring's control. You should be using either Spring's @RemotingDestination, or <flex:remoting-destination>.

    3) Unless you're trying to use the new RESTful AMF support in 1.5.0.M2 (which is not the common case, and I see no sign of it in your configuration), it really doesn't make sense to be calling @Controller classes from Flex. You would typically call your service class directly instead.

    I would recommend starting here to get an understanding of how Spring BlazeDS works:
    http://blog.springsource.com/2009/06...ntegration-10/

    There are several other good learning resources in the "Articles and Tutorials" section of http://www.springsource.org/spring-flex

    Comment


    • #3
      Thank you Jeremy for your very quick response. i've already made some changes per your recommendations.
      Originally posted by jeremyg484 View Post
      2) When using Spring BlazeDS, you should not need the <security> section, nor the <services> section in services-config.xml. The explicit definition of the Controller as a RemotingDestination using the non-Spring BlazeDS configuration is the thing that is causing the Controller to be instantiated outside of Spring's control. You should be using either Spring's @RemotingDestination, or <flex:remoting-destination>.
      i was able to get it to work with the @RemotingDestination annotation, but not with the xml configuration.
      Originally posted by jeremyg484 View Post
      3) Unless you're trying to use the new RESTful AMF support in 1.5.0.M2 (which is not the common case, and I see no sign of it in your configuration), it really doesn't make sense to be calling @Controller classes from Flex. You would typically call your service class directly instead.
      I have removed the @Controller annotation actually but am still calling this class from Flex as we tend to prefer having a first layer on top of the service class to manage business rules and whatnot.

      Thank you very much again for your help

      Comment


      • #4
        forgot to ask an other question, this time on the Flex side.
        I've defined my remote object as such:
        Code:
        var channels:ChannelSet = new ChannelSet();
        var simpleChannel:Channel = new AMFChannel("my-amf", "http://localhost:8080/flexsample/messagebroker/amf");
        channels.addChannel(simpleChannel);
        
        ro = new RemoteObject("flexSampleService");
        ro.channelSet = channels;
        is there a way to not have the channel definition hardcoded? this is important as the application will be used on several different platforms.
        Last edited by pier; Feb 16th, 2011, 01:41 PM. Reason: replaced "amfChannel" by "my-afm" to fit with services-config.xml

        Comment


        • #5
          is there a way to not have the channel definition hardcoded?
          Code:
          var simpleChannel:Channel = ServerConfig.getChannel("amfChannel");

          Comment


          • #6
            thanx.
            unfortunately when i do this, it tells me
            'Channel 'amfChannel' does not exist in the configuration.'

            when i look up serverConfigData and the xml,
            Code:
            var serverConfigData:XML = ServerConfig.serverConfigData;
            var xml:XML = ServerConfig.xml;
            i get null for the former and <services/> for the latter

            so i'm guessing it's not able to retrieve the configuration correctly?

            Comment


            • #7
              unfortunately when i do this, it tells me
              'Channel 'amfChannel' does not exist in the configuration.'
              You have "amfChannel" defined in services-config.xml file right?

              Code:
              		
              <channel-definition id="amfChannel" class="mx.messaging.channels.AMFChannel">
              	<endpoint url="http://{server.name}:server.port}/flexsample/messagebroker/amf" class="flex.messaging.endpoints.AMFEndpoint" />
              </channel-definition>

              Comment


              • #8
                IIRC, you have to actually compile against services-config.xml in order for ServerConfig.getChannel to work, don't you? Meaning you would have to recompile the .swf anytime you want to change the AMF channel config. This is why I generally recommend externalizing the configuration using Spring ActionScript (or any of the other Flex DI options).

                There is a nice example of this that someone wrote up here not too long ago that might be helpful:
                http://forum.springsource.org/showthread.php?t=95754

                Comment


                • #9
                  @amiladomingo yes
                  i've actually been using the id "my-amf" in reality, as per the config in services-config.xml in the original post. don't know why i put amfChannel in the Flex code.
                  Regardless, it's "my-amf" in the definition on the server side and in the call on the flex side

                  FYI, forgot to mention i'm working with Flex 3, not 4. in case that might have any impact

                  Thanks Jeremy, gonna check that out.

                  Comment

                  Working...
                  X