Raible's Wiki

Raible Designs
Wiki Home
News
Recent Changes

AppFuse

Homepage
  - Korean
  - Chinese
  - Italian
  - Japanese

QuickStart Guide
  - Chinese
  - French
  - German
  - Italian
  - Korean
  - Portuguese
  - Spanish
  - Japanese

User Guide
  - Korean
  - Chinese

Tutorials
  - Chinese
  - German
  - Italian
  - Korean
  - Portuguese
  - Spanish

FAQ
  - Korean

Latest Downloads

Other Applications

Struts Resume
Security Example
Struts Menu

Set your name in
UserPreferences


Referenced by
Articles
Articles_de
Articles_pt
Articles_zh




JSPWiki v2.2.33

[RSS]


Hide Menu

RichClient


Difference between version 35 and version 23:

At line 1 added 297 lines.
''Please note that this tutorial is under development and there are still some unsolved issues. If you find solutions to any of them I would very much appreciate your help. Contact: [Radim Burget|RadimBurget]''
!Table of Contents
* [1] About Spring-rcp
* [2] Configuring Appfuse - map servlet to be listening on "ws/*" url address
* [3] Configuring Appfuse - create ws servlet
* [4] Configuring Appfuse - add *.jar library dependencies
* [5] Configuring Appfuse - add interface to allow remote client logins
* [6] Configuring RichClient - source code
* [7] Configuring RichClient - libraries
* [8] Unsolved issues
----
!!! About Spring-rcp [#1]
The goal of the [spring-richclient project|http://www.springframework.org/spring-rcp] is to provide a viable option for developers that need a platform and 'best-practices' guide for constructing professional Swing applications quickly.
My work is based on the Spring-rcp Pet Clinic Demo (in [CVS|http://sourceforge.net/cvs/?group_id=113660] only) and my efforts in integrating it with Appfuse.
%%(border: 1px solid black; margin: 0 auto; height: 380px; width: 455px)
[RichClient/screenshot1.jpg]
%%
!!! Configuring Appfuse - map servlet to be listening on "ws/*" url address [#2]
Add this portion of code to metadata/web/__servlets.xml__
<div style="margin-left: 40px">
{{{
<!-- REMOTE ACCESS SERVELTET -->
<servlet>
<servlet-name>ws</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<load-on-startup>2</load-on-startup>
</servlet>
<!--
- Dispatcher servlet mapping for HTTP web services.
- (see ws-servlet.xml for the controllers).
-->
<servlet-mapping>
<servlet-name>ws</servlet-name>
<url-pattern>/ws/*</url-pattern>
</servlet-mapping>
}}}
</div>
!!! Configuring Appfuse - create ws servlet[#3]
Create a ws servlet XML beans descriptor. Because I am using [Hessian|http://www.caucho.com/hessian/] instead of [Burlap|http://www.caucho.com/burlap/burlap.xtp] I have commented out Burlap-specific portions of the code. If you ever want to use Burlap instead just uncomment this part of the code.
The main difference between Hessian and Burlap is that Hessian is binary and Burlap is XML-based.
<div style="margin-left: 40px">
{{{
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd">
<!--
- $Id: ws-servlet.xml,v 1.1 2004/08/01 23:03:20 benalex Exp $
-->
<beans>
<!-- Hessian exporter for the Clinic -->
<!-- Hessian is a slim binary HTTP remoting protocol -->
<bean name="/Clinic-hessian" class="org.springframework.remoting.caucho.HessianServiceExporter">
<property name="service"><ref bean="userManager"/></property>
<property name="serviceInterface">
<value>org.appfuse.service.UserManager</value>
</property>
</bean>
<!-- Burlap exporter for the Clinic -->
<!-- Burlap is a slim XML-based HTTP remoting protocol -->
<!--bean name="/Clinic-burlap" class="org.springframework.remoting.caucho.BurlapServiceExporter">
<property name="service"><ref bean="clinic"/></property>
<property name="serviceInterface">
<value>org.springframework.samples.petclinic.Clinic</value>
</property>
</bean-->
<!-- Hessian exporter for the RemoteAuthenticationManager -->
<bean name="/RemoteAuthenticationManager-hessian" class="org.springframework.remoting.caucho.HessianServiceExporter">
<property name="service"><ref bean="remoteAuthenticationManager"/></property>
<property name="serviceInterface">
<value>net.sf.acegisecurity.providers.rcp.RemoteAuthenticationManager</value>
</property>
</bean>
<!-- Burlap exporter for the RemoteAuthenticationManager -->
<!--bean name="/RemoteAuthenticationManager-burlap" class="org.springframework.remoting.caucho.BurlapServiceExporter">
<property name="service"><ref bean="remoteAuthenticationManager"/></property>
<property name="serviceInterface">
<value>net.sf.acegisecurity.providers.rcp.RemoteAuthenticationManager</value>
</property>
</bean-->
</beans>
}}}
</div>
!!! Configuring Appfuse - add *.jar library dependencies [#4]
For more details read [how to add a library into appfuse|http://raibledesigns.com/wiki/Wiki.jsp?page=AppFuseAddLibrary] here.
Copy hessian.jar to appfuse/lib/hessian/hessian.jar
In lib/lib.properties add path info:
<div style="margin-left: 40px">
{{{
#
# Hessian
#
hessian.version=0.1
hessian.dir=${lib.dir}/hessian-${hessian.version}
hessian.jar=${hessian.dir}/hessian-${hessian.version}.jar
}}}
</div>
If you will ever need burlap do the same with the burlap *.jar files.
Add to __build.xml__ the hessian library dependency:
<div style="margin-left: 40px">
{{{
<target name="package-web" ......
.......
......
<lib file="${hessian.jar}"/>
......
</target>
}}}
</div>
(properties.xml does not need any changes)
!!!Configuring Appfuse - add interface to allow remote client logins[#5]
Add this bean to web/WEB-INF/__applicationContextSecurity.xml__:
<div style="margin-left: 40px">
{{{
<!-- Allows remote clients to check if a username/password is valid -->
<bean id="remoteAuthenticationManager" class="net.sf.acegisecurity.providers.rcp.RemoteAuthenticationManagerImpl">
<property name="authenticationManager"><ref bean="authenticationManager"/></property>
</bean>
}}}
</div>
!!! Configuring RichClient - source code[#6]
Download the [Appfuse Rich Client source code|http://raibledesigns.com/wiki/attach?page=RichClient%2Fappfuse-richclient.zip] and copy them to your Appfuse project.
%%note __NOTE__ At first I tried to create a new standalone project that referenced the Appfuse project but was independent from it. Unfortunately I had some issues with compilation so I decided to integrate it directly to the project.%%
!!! Configuring RichClient - libraries [#7]
You will need to download these jar archives and add them to the Eclipse classpath (Eclipse: Project/Properties/Java Build Path/Libraries/Add JARs). Be sure not to forget to refresh the appfuse directory structure afterwards.
<div style="margin-left: 40px">
{{{
appfuse/lib
/caucho
(84 871) burlap.jar
(83 245) hessian.jar
/jgoodies
(85 502) forms.jar
(338 486) looks.jar
/spring-rcp
(366 615) spring-richclient-resources.jar
(59 691) spring-richclient-sandbox.jar
(736 813) spring-richclient.jar
/javahelp
(531 676) javahelp.jar
/spring
(741 379) spring-sandbox.jar
}}}
</div>
My collection of JAR files can be downloaded from [here|http://raibledesigns.com/wiki/attach?page=RichClient%2Flib.zip].
Now you should be able to compile and run your application (org.appfuse.richclient.PetClinicClientServer)
%%note __NOTE:__ Please ensure that your server is running ([http://localhost:8080/appfuse/ws/Clinic-hessian| http://localhost:8080/appfuse/ws/Clinic-hessian] displays exception "HessianServiceExporter only supports POST requests")%%
!!! Unsolved issues [#8]
** On successfull login is thrown Exception ClassNotFoundException: net.sf.acegisecurity.context.SecureContextImpl
** on __userManager.getUsers(null)__ exception :
org.hibernate.LazyInitializationException
!! ClassNotFoundException
Username is not yet crypted so I recomend to add new user to your database with __username__:test, __password__:test.
On unsuccessful login everything is OK and is shown "Bad Credentials" message.
On unsuccessfull login is thrown exception - In each appfusem 1.8 is in classpath included __lib\spring-1.2-rc2\acegi-security-0.8.2.jar__ which contains net.sf.acegisecurity.context.security.__SecureContextImpl__ class so I dont know where should be the problem :(
<div style="margin-left: 40px">
{{{
java.lang.NoClassDefFoundError
at org.springframework.richclient.security.SessionDetails.class$(SessionDetails.java:97)
at org.springframework.richclient.security.SessionDetails.getSecureContextClass(SessionDetails.java:97)
at org.springframework.richclient.security.SessionDetails.login(SessionDetails.java:110)
at org.springframework.richclient.security.LoginForm.commit(LoginForm.java:57)
at org.springframework.richclient.security.LoginCommand$1.onFinish(LoginCommand.java:79)
at org.springframework.richclient.dialog.ApplicationDialog$1.doExecuteCommand(ApplicationDialog.java:322)
at org.springframework.richclient.command.ActionCommand.execute(ActionCommand.java:188)
at org.springframework.richclient.command.ActionCommand$1.actionPerformed(ActionCommand.java:123)
at javax.swing.AbstractButton.fireActionPerformed(Unknown Source)
at javax.swing.AbstractButton$ForwardActionEvents.actionPerformed(Unknown Source)
at javax.swing.DefaultButtonModel.fireActionPerformed(Unknown Source)
at javax.swing.DefaultButtonModel.setPressed(Unknown Source)
at javax.swing.plaf.basic.BasicButtonListener.mouseReleased(Unknown Source)
at java.awt.Component.processMouseEvent(Unknown Source)
at java.awt.Component.processEvent(Unknown Source)
at java.awt.Container.processEvent(Unknown Source)
at java.awt.Component.dispatchEventImpl(Unknown Source)
at java.awt.Container.dispatchEventImpl(Unknown Source)
at java.awt.Component.dispatchEvent(Unknown Source)
at java.awt.LightweightDispatcher.retargetMouseEvent(Unknown Source)
at java.awt.LightweightDispatcher.processMouseEvent(Unknown Source)
at java.awt.LightweightDispatcher.dispatchEvent(Unknown Source)
at java.awt.Container.dispatchEventImpl(Unknown Source)
at java.awt.Window.dispatchEventImpl(Unknown Source)
at java.awt.Component.dispatchEvent(Unknown Source)
at java.awt.EventQueue.dispatchEvent(Unknown Source)
at java.awt.EventDispatchThread.pumpOneEventForHierarchy(Unknown Source)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source)
at java.awt.Dialog$1.run(Unknown Source)
at java.awt.event.InvocationEvent.dispatch(Unknown Source)
at java.awt.EventQueue.dispatchEvent(Unknown Source)
at java.awt.EventDispatchThread.pumpOneEventForHierarchy(Unknown Source)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source)
at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
at java.awt.EventDispatchThread.run(Unknown Source)
Caused by: java.lang.ClassNotFoundException: net.sf.acegisecurity.context.SecureContextImpl
at java.net.URLClassLoader$1.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(Unknown Source)
at java.lang.ClassLoader.loadClass(Unknown Source)
at sun.misc.Launcher$AppClassLoader.loadClass(Unknown Source)
at java.lang.ClassLoader.loadClass(Unknown Source)
at java.lang.ClassLoader.loadClassInternal(Unknown Source)
at java.lang.Class.forName0(Native Method)
at java.lang.Class.forName(Unknown Source)
... 37 more
}}}
</div>
!! LazyInitializationException
<div style="margin-left: 40px">
{{{
org.hibernate.LazyInitializationException: failed to lazily initialize a collection - no session or session was closed
at org.hibernate.collection.AbstractPersistentCollection.initialize(AbstractPersistentCollection.java:180)
at org.hibernate.collection.AbstractPersistentCollection.write(AbstractPersistentCollection.java:61)
at org.hibernate.collection.PersistentSet.add(PersistentSet.java:158)
at com.caucho.hessian.io.CollectionDeserializer.readList(CollectionDeserializer.java:97)
at com.caucho.hessian.io.HessianInput.readObject(HessianInput.java:674)
at com.caucho.hessian.io.JavaDeserializer.readMap(JavaDeserializer.java:135)
at com.caucho.hessian.io.JavaDeserializer.readMap(JavaDeserializer.java:114)
at com.caucho.hessian.io.SerializerFactory.readMap(SerializerFactory.java:147)
at com.caucho.hessian.io.HessianInput.readObject(HessianInput.java:781)
at com.caucho.hessian.io.CollectionDeserializer.readList(CollectionDeserializer.java:97)
at com.caucho.hessian.io.HessianInput.readObject(HessianInput.java:678)
at com.caucho.hessian.io.HessianInput.readReply(HessianInput.java:241)
at com.caucho.hessian.client.HessianProxy.invoke(HessianProxy.java:179)
at $Proxy0.getUsers(Unknown Source)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at org.springframework.remoting.caucho.HessianClientInterceptor.invoke(HessianClientInterceptor.java:115)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:144)
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:174)
at $Proxy1.getUsers(Unknown Source)
at org.appfuse.richclient.ui.OwnerManagerView.createOwnerManagerTree(OwnerManagerView.java:127)
at org.appfuse.richclient.ui.OwnerManagerView.createControl(OwnerManagerView.java:117)
at org.springframework.richclient.factory.AbstractControlFactory.getControl(AbstractControlFactory.java:48)
at org.springframework.richclient.application.support.DefaultApplicationPage.createPageComponent(DefaultApplicationPage.java:71)
at org.springframework.richclient.application.support.AbstractApplicationPage.showView(AbstractApplicationPage.java:155)
at org.springframework.richclient.application.support.AbstractApplicationPage.showView(AbstractApplicationPage.java:186)
at org.springframework.richclient.application.support.DefaultApplicationPage.addView(DefaultApplicationPage.java:78)
at org.springframework.richclient.application.support.SingleViewPageDescriptor.buildInitialLayout(SingleViewPageDescriptor.java:60)
at org.springframework.richclient.application.support.DefaultApplicationPage.getControl(DefaultApplicationPage.java:45)
at org.springframework.richclient.application.support.DefaultApplicationWindow.applyCustomLayout(DefaultApplicationWindow.java:235)
at org.springframework.richclient.application.support.DefaultApplicationWindow.initWindowControl(DefaultApplicationWindow.java:220)
at org.springframework.richclient.application.support.DefaultApplicationWindow.initWindow(DefaultApplicationWindow.java:210)
at org.springframework.richclient.application.support.DefaultApplicationWindow.showPage(DefaultApplicationWindow.java:151)
at org.springframework.richclient.application.Application.openWindow(Application.java:163)
at org.springframework.richclient.application.ApplicationLauncher.launchMyRichClient(ApplicationLauncher.java:178)
at org.springframework.richclient.application.ApplicationLauncher.<init>(ApplicationLauncher.java:100)
at org.appfuse.richclient.PetClinicClientServer.main(PetClinicClientServer.java:41)
}}}
</div>

Back to RichClient, or to the Page History.