Project

General

Profile

TaxonomicEditorDevelopersGuide » History » Revision 188

Revision 187 (Andreas Kohlbecker, 07/25/2016 01:14 PM) → Revision 188/246 (Andreas Kohlbecker, 10/12/2016 09:11 AM)

# Taxonomic Editor Developers Guide 


 


 This page contains all information related to developing with the Taxonomic Editor, with additional information regarding [[#Remoting|Remoting]]. 

 

 {{>toc}} 




 




 ## Development Environment 

 

 This section deals with the setup of the development environment for the Taxonomic Editor. The setup has been tested with [Eclipse Luna (4.4)](https://www.eclipse.org/luna/,) but may work with later versions. 


 


 ### Installation 

 

 Refer to http://cybertaxonomy.eu/taxeditor/getting-started.html 


 


 ### Target RCP Environment 

 

 To configure the target RCP environment, 

 

 * Open the **rcp.target** file in the _eu.etaxonomy.taxeditor_ project 

 

 * For the nebula site click on "edit" and select the Composite Table Widget 

 

 * Select the three software sites and hit *update*. This will compute the dependencies of the various plugins and retrieve them to give a result which looks like 

 {{thumbnail(editor-luna-rcp-target.png, size=800)}} 
 

 ![](editor-luna-rcp-target.png) 
 ~~~ 
 
 <code class="html"> 
 
 <font color="red">Warning : Due to a bug related to this functionality in Eclipse the update may not happen immediately, giving errors like 'Unable to locate ..'. In this case restart Eclipse and redo the above two steps.</font> 
 
 ~~~ 

 

 To setup the workspace to use the rcp target  

  

 * Open the Preferences panel (Window -> Preferences) and select Plug-in Development -> Target Platform. 

 

 * Select the **Eclipse Indigo Target*. If you see 'Unable to locate ..' errors in the *Locations view** then hit **Reload** to fix these. Hit **Apply** to use the chosen rcp target for the development environment. 

 

 ![](editor-luna-set-target.png) 
 
 * Delete the _eu.etaxonomy.taxeditor.application.product_ configuration from the Run/Debug configurations if it exists because you have worked with a prior version before. 

 

 * Right click on the _eu.etaxonomy.taxeditor.application_ project and choose Run as -> Eclipse Application to create new launch configurations for Run / Debug. 



 



 ### Editor / Server Setup 

 

 This section contains the different editor /server combinations that can be used for testing 


 


 #### Eclipse : Editor / Server 

 

 This section provides details on how to setup the standard development environment with the editor and server both launched from the eclipse workspace.  


  


 ##### Server Side 

 

 Check that the _cdmlib-remote-webapp - run_ configuration has jetty port set as **8080** and that the VM arguments includes, 

 

 ~~~ 
 
 -Dspring.profiles.active=remoting 
 
 ~~~ 

 

 ##### Editor Side 

 

 Edit the _eu.etaxonomy.taxeditor.application.product_ debug / runtime configuration to add the VM arguments 

 

 ~~~ 
 
 -Dcdm.server.dev.port=8080  
  
 -Dcdm.server.dev.username=<username> 
 
 -Dcdm.server.dev.password=<password> 
 
 ~~~ 
 
 This will force the editor to always automatically connect to the server running on port 8080. 


 


 The editor login mechanism checks against the timestamp of the cdmlib-services jar and will not allow a connection if the timestamp is not exactly the same. This can be problematic in development when the timestamps may differ for SNAPSHOT versions. To bypass this check, add 

 

 ~~~ 
 
 -Dcdm.server.version.lm.ignore=true 
 
 ~~~ 
 
 to the above product configurations. 


 


 ##### Runtime 

 

 * Launch the _cdmlib-remote-webapp - run_ configuration and wait for the server to start up. 

 

 * Launch the editor from the eclipse workspace using the _eu.etaxonomy.taxeditor.application.product_ configuration.  

 
  

 
 * Click on **General->Connect** and the editor should directly connect to the server launched from the eclipse workspace. 


 


 ##### Notes 

 

 This environment allows developers to edit code live as eclipse hot swaps the code for both editor and server. In the case of changes in class structure (i.e. changes in method signature, addition of new methods, changes in static members, etc) eclipse will ask for the running process to be termintated. In the case where these changes apply to code shared by the editor (service layer, model, etc), executing **mvn validate** on the _eu.etaxonomy.taxeditor.cdmlib_ project will be required. 



 



 #### Eclipse : JUnit Plugin Tests / Server 

 

 This section provides details on how to setup the unit test environment for the editor targeting a manually launched server from the eclipse workspace. 

 

 ##### Server Side 

 Check that the _cdmlib-remote-webapp-unit-tests_ configuration has jetty port set as **9090** and that the VM arguments includes, 

 ~~~ 
 -Dspring.profiles.active=remoting 
 ~~~ 
 The configuration for the server using the editor test db is described in the diagram below. 


 ![](testing.png)      

 Setting up the server side includes, 

 * adding the taxeditor test datasource to the **<path/to/home/dir/>.cdmLibrary/datasources.xml**  

 ~~~ 
     <bean id="local-cdmTest"    lazy-init="true" class="com.mchange.v2.c3p0.ComboPooledDataSource"> 
         <property name="driverClass" value="eu.etaxonomy.cdm.database.LocalH2"/> 
         <property name="user" value="sa"/> 
         <property name="password" value=""/> 
         <property name="jdbcUrl" value="jdbc:h2:file:/path/to/taxeditor-project/eu.etaxonomy.taxeditor.test/target/classes/h2/cdmTest;AUTO_SERVER=TRUE"/> 
     </bean> 
 ~~~ 
 * activating the above datasource as the default one. This can set in the **<path/to/home/dir/>.cdmLibrary/cdmlib-remote** properties file by adding  

  <pre> 

    cdm.datasource=local-cdmTest  

 </pre> 

  or in the above run/debug configuration by adding  

  <pre> 

    -Dcdm.datasource=local-cdmTest  

 </pre>  

  as VM argument. 

 

 ##### Editor Side 

 

 The tests reside in the _eu.etaxonomy.taxeditor.test_ project and uses the settings in **src/test/resources/server.properties**  


  


 ##### Runtime 

 

 * Launch the _cdmlib-remote-webapp-unit-tests_ configuration and wait for the server to start up. 

 

 * Launch any unit test by choosing the **Run / Debug As - > JUnit Plug-in Test** option in the right-click menu. 


 


 ##### Notes 

 

 The **JUnit Plug-in Test** choice is important since this will ensure that the test is run in the RCP environment.  


  


 The live coding and debug possibilities are similar to the editor / server environment. 



 



 #### Maven : JUnit Plugin Tests / Server 

 

 This section provides details on the environment for running automated tests using maven. 


 


 ##### Server Side 

 

 The maven configuration in the _eu.etaxonomy.taxeditor.test_ project has been setup launch a jetty server with the **cdmlib-remote-webapp.war** from the _eu.etaxonomy.taxeditor.cdmlib_ project on port **9090** using the **datasources.xml** file located in _src/test/resources_ which contains the local cdm h2 test db as target datasource. 


 


 ##### Editor Side 

 

 All tests in the _eu.etaxonomy.taxeditor.test_ project can be run. 


 


 ##### Runtime 

 

 Refer to the [[#Testing|Testing]] section for details on maven goals. 



 



 #### Eclipse Editor with Remote Server 

 

 This section provides details on how to setup the development environment for the editor targeting a remote server. 


 


 ##### Server Side 

 

 Ensure that the remote cdmserver is running and has the remoting flag activated. 


 


 ##### Editor Side 

 

 Duplicate the _eu.etaxonomy.taxeditor.application.product_ configuration to say _eu.etaxonomy.taxeditor.application.product.remote_ and remove the **cdm.server.dev.*** VM arguments. 


 


 The editor login mechanism checks against the timestamp of the cdmlib-services jar and will not allow a connection if the timestamp is not exactly the same. This can be problematic in development when the timestamps may differ for SNAPSHOT versions. To bypass this check, add 

 

 ~~~ 
 
 -Dcdm.server.version.lm.ignore=true 
 
 ~~~ 
 
 to the above product configurations. 


 


 ##### Runtime 

 

 * Launch the editor from the eclipse workspace using the _eu.etaxonomy.taxeditor.application.product_ configuration.  

 
  

 
 * Click on **General->Connect** and the editor will display the remoting login dialog which will allow you to connect to the target server. 



 



 ### Logging 

 

 There exists two logging configuration files which can be used for debugging purposes : 

 

 * **eu.etaxonomy.taxeditor.cdmlb/src/main/resources/log4j.xml** : the only log config file installed in the final product. 

 

 * **eu.etaxonomy.taxeditor.test/src/test/resources/log4j.xml** : the log file within the test plugin. 

 

 

 

 ### Test Framework 

 

 The testing framework resides in the **eu.etaxonomy.taxeditor.test** plugin and consists of the following categories of tests, 

 

 * **Base Tests** : which mainly test the http-invoker layer. These tests should sub-class _eu.etaxonomy.taxeditor.httpinvoker.BaseRemotingTest_. 

 

 * **Session Aware Tests** : which mainly test the cdm entity sessions. These tests should sub-class _eu.etaxonomy.taxeditor.httpinvoker.RemotingSessionAwareTest_. 

 

 * **Operation Tests** : which mainly test the editor operations. Thse tests should sub-class _eu.etaxonomy.taxeditor.operation.BaseOperationTest_. 

 

 For running the tests in Eclipse refer to [[#EclipseJUnitPluginTestsServer|Eclipse : JUnit Plugin Tests / Server]] and for Maven refer to [[#MavenJUnitPluginTestsServer|Maven : JUnit Plugin Tests / Server]]. 


 


 ## Deployment 


 


 ### P2 Updates 

 

 Eclipse RCP provides a mechanism for self updates via the [Equinox/p2 Self-Update](https://wiki.eclipse.org/Equinox/p2/Adding_Self-Update_to_an_RCP_Application) functionality.  


  


 The p2 configuration for the editor is configured in the 'uploadRepo' profile of **eu.etaxonomy.taxeditor/pom.xml** which uploads the relevant files required for the update mechanism to the given update site using specific [[#P2UpdatesUpload|maven goals]]. 



 



 ### Custom JRE Packaging 

 

 Eclipse RCP allows for bundling a custom JRE along with the final product. 


 


 For the editor the custom JRE is currently included in the **eu.etaxonomy.taxeditor.feature** plugin and is managed using, 

 

 * the **eu.etaxonomy.taxeditor.feature/build.properties.with.jre** which is used to append the jre specific properties to the **eu.etaxonomy.taxeditor.feature/build.properties** file. 

 

 * the **eu.etaxonomy.taxeditor/eu.etaxonomy.taxeditor.product.with.jre** product definition file which is used to replace the standard product definition file when the jre bundled package is generated. 

 

 * the **server-scripts/jenkins-ci/taxeditor/setup-jre-bundle.sh** script which setups up the project to include the jre bundle. This script should ALWAYS be run before running the maven goals. 

 

 * the specific [[#JREBundling|maven goals]] to be run for generating the product bundled with the jre. 

 

 NOTE : This configuration will change with the resolution of ticket [5430](https://dev.e-taxonomy.eu/trac/ticket/5430.) 



 



 ### Continuous Integration 

 

 The jenkins jobs related to the Taxonomic editor include, 

 

 * [taxeditor-INTEGRATION](http://int.e-taxonomy.eu/jenkins/view/EDIT%20Taxonomic%20Editor/job/taxeditor-INTEGRATION) : which packages the 'develop' branch and deploys both the final product and the p2 updates. 

 

 * [taxeditor-JRE-INTEGRATION](http://int.e-taxonomy.eu/jenkins/view/EDIT%20Taxonomic%20Editor/job/taxeditor-JRE-INTEGRATION) : which packages the 'develop' branch and deploys both the final product and the p2 updates with the relevant jre bundle. 

 

 * [taxeditor-SNAPSHOT](http://int.e-taxonomy.eu/jenkins/view/EDIT%20Taxonomic%20Editor/job/taxeditor-SNAPSHOT) : which packages the chosen branch and deploys both the final product and the p2 updates to the chosen update site directory. 

 

 * [taxeditor-JRE-SNAPSHOT](http://int.e-taxonomy.eu/jenkins/view/EDIT%20Taxonomic%20Editor/job/taxeditor-JRE-SNAPSHOT) : which packages the chosen branch and deploys both the final product and the p2 updates with the relevant jre bundle to the chosen update site directory. 



 



 ### Performing a Release / Hotfix 


 


 #### Release Jobs 

 

 A release can be performed by executing the following jobs in the given order, 

 

 * [taxeditor-RLS-START](http://int.e-taxonomy.eu/jenkins/view/EDIT%20Taxonomic%20Editor/job/taxeditor-RLS-START) to start the release. 

 

 * [taxeditor-RLS-FINISH](http://int.e-taxonomy.eu/jenkins/view/EDIT%20Taxonomic%20Editor/job/taxeditor-RLS-FINISH) to finish the release. 



 



 #### Hotfix Jobs 

 

 A hotfix can be performed by executing the following jobs in the given order, 

 

 * [taxeditor-HFX-START](http://int.e-taxonomy.eu/jenkins/view/EDIT%20Taxonomic%20Editor/job/taxeditor-HFX-START) to start the hotfix. 

 

 * [taxeditor-HFX-FINISH](http://int.e-taxonomy.eu/jenkins/view/EDIT%20Taxonomic%20Editor/job/taxeditor-HFX-FINISH) to finish the hotfix. 



 



 #### Post Release / Hotfix 

 

 * [Taxonomic Editor/job/taxeditor-RELEASE taxeditor-RELEASE](http://int.e-taxonomy.eu/jenkins/view/EDIT) to install the product and p2 updates in the taxeditor download directory. 

 

 * [Taxonomic Editor/job/taxeditor-DEPLOY-ULTEO taxeditor-DEPLOY-ULTEO](http://int.e-taxonomy.eu/jenkins/view/EDIT) to deploy the final product to the corresponding directory on the ulteo server. 




 




 ## Maven Goals 

 

 The maven goals available within the editor project are as follows : 


 


 ### Generate the product files 
 
 
 
 In order to generate the final products execute **mvn package -P buildProducts** in the taxeditor parent project. 


 


 ### Copy dependent jars 

 

 * To update the dependent jars in all projects , execute **mvn clean validate** in the taxeditor parent project.  

  

 * For updating only individual projects (list below), the **mvn clean validate** command should be run in the project directory.  

    

   * _eu.etaxonomy.taxeditor.cdmlib_ 

   

   * _eu.etaxonomy.taxeditor.molecular.lib_ 

   

   * _eu.etaxonomy.taxeditor.webapp_ 

 

 * To force the use of locally installed dependent jars, execute **mvn clean validate -Plocal-repository -Dlocalrepo=</path/to/local/m2/repository>**  


  


 ### P2 Updates Upload 

 

 To install the relevant files for the p2 update site, execute **mvn package -P uploadRepo -Dupdate.dir=<update.dir>*, where *<update.dir** is the name of the directory in the remote edit download update site directory _http://wp5.e-taxonomy.eu/var/www/download/taxeditor/update_ into which the updates will be installed. 


 


 ### JRE Bundling 

 

 To bundle a specific JRE along with the final product first run the **server-scripts/jenkins-ci/taxeditor/setup-jre-bundle.sh** script in the taxedtor parent directory and then the maven goal : * mvn package    -P buildProducts -Dproduct.id=eu.etaxonomy.taxeditor.product.jre* 


 


 ### Testing 

 

 Before running any test, execute mvn install in the taxeditor parent project. This will install all taxeditor projects which is required for the mvn tests to run with the latest compiled code base.  


  


 Once the projects have been installed, the usual maven test goals are available to be executed from the eu.etaxonomy.taxeditor.test project directory. These include, 

 

 * Executing mvn integration-test for running all tests. 

 

 * Executing mvn test -Dtest=<fully.qualified.class.Name> for running a single test class.  



  



 ## Model Change Actions 

 

 The actions required following a model change include, 


 


 ### CDM h2 Test DB update 

 

 * Generate new empty CDM h2 db. 

 

 * Replace the existing **src/test/resources/h2/cdmTest.h2.db** in the _eu.etaxonomy.taxeditor.test_ project with the newly generated one. 


 


 ### CDM Hibernate Serialised mapping update 

 

 * Copy the latest cdmlib **hibernate.cfg.xml** to **src/main/resources/eu/etaxonomy/cdm/mappings/hibernate.cfg.xml** in the _eu.etaxonomy.taxeditor.cdmlib_ project. 

 

 * Execute **mvn exec:java -Dexec.mainClass="eu.etaxonomy.taxeditor.remoting.cache.CdmModelCacher"** in the _eu.etaxonomy.taxeditor.cdmlib_ project dir. 

 

 This will generate a new **cdm.map.ser** file in the _resources_ directory. 

 

 ## Remoting 

 Remoting can be generally described as a client-server architecture where the client is able to access the server's service layer api directly, as if the api were available locally. 


 Out of the many    [implementations](http://docs.spring.io/spring/docs/current/spring-framework-reference/html/remoting.html)    of Spring Remoting,    [HttpInvoker](http://docs.spring.io/spring-integration/docs/2.0.x/reference/html/httpinvoker.html)    has been chosen primarily due to the fact that it is open source, works over http, (comparatively) easy to configure and can be extended as required. 


 The configuration on the client - taxonomic editor side is made up of the following classes, 

 * **eu.etaxonomy.taxeditor.cdmlib** - _eu.etaxonomy.taxeditor.service.CdmAuthenticatedHttpInvokerRequestExecutor_ : which is responsible for adding the authentication to the http headers. 

 * **eu.etaxonomy.taxeditor.cdmlib** - _eu.etaxonomy.taxeditor.service.CdmServiceRequestExecutor_ : which acts as the gateway for all service requests and is responsible for loading Cdm Entity objects into the active [[#RemotingSessionArchitecture|remoting session]] 

 * **eu.etaxonomy.taxeditor.cdmlib** - _eu.etaxonomy.cdm.api.application.CdmApplicationRemoteConfiguration_ : which programmatically generates the service classes using the above mentioned _CdmServiceRequestExecutor_ class. 

 *NOTE*: As compared to the stand-alone version of the taxonomic editor, the remoting version does not use any spring application context xml files. The reason for moving all the xml file based configuration to programmatic configuration is due to the slow loading of the beans declared in the file based application context from within the Eclipse RCP framework. 


 The configuration on the cdm server side is made up of the following configuration files, 

 * **cdmlib-services** - _httpInvokerServices.xml_ : where the service beans to expose over remoting are actually registered. 

 * **cdmlib-services** - _remoting-services.xml_ : which declares the mapping between the remoting endpoints and the registered service beans. 

 * **cdmlib-remote** - _remote-security_ : which configures the url endpoint security for the remoting endpoints 


 An overview of both taxonomic editor and cdmlib can be seen below. 


 ![](remotingconfig.png) 




 ### Eager Lazy Loading 

 Eager Lazy Loading is the process of loading (previously lazy loaded) entities on demand as and when any attempt is made to initialise proxies. The two classes responsible for performing the initialisation, 

 * org.hibernate.proxy.AbstractLazyInitializer (initialises entity proxies) 

 * org.hibernate.collection.internal.AbstractPersistentCollection (initialises entity collections) 

 have been overriden in the _eu.etaxonomy.taxeditor.cdmlib_ project.  


 Instead of using (or generating) hibernate sessions to initialise the entity / collection, these overriding custom classes load them using relevant service methods as seen below. 

 ![](eagerlazyloading.png)   



 ### Remoting Sessions Architecture 

 In the context of the remoting framework, the taxonomic editor retrieves and manages the hibernate based domain objects exposed by the remoting cdmlib services.  


 In order to effectively manage the domain objects, it has become necessary integrate sessions within the taxonomic editor. The reasons for this requirement include, 

 * caching of domain objects : This will reduce the number of server-side service calls. 

 * domain object similarity : Updating hibernate based domain objects remotely requires that all objects in the object sub graph to be updated which are equal should also be the same (i.e. for objects a and b this means that if a.equals(b), then a == b), which can be guaranteed by the use of sessions. 

 * memory usage boundaries : If the memory used by the taxonomic editor when loading domain objects for specific ui elements is not optimised, this may lead to memory leaks with the possibility of the application running out of memory. The use of sessions linked to ui elements clearly demarcates the domain objects loaded and used for individual sessions, which can be disposed of easily when the ui element itself is disposed. 


 As seen in the diagram below, the sessions architecture is made up of, 

 * **eu.etaxonomy.taxeditor.cdmlib** - _eu.etaxonomy.taxeditor.remoting.cache.CdmTransientEntityCacher_ : the class responsible for caching CDM entities within the scope of a remoting session. 

 * **eu.etaxonomy.taxeditor.cdmlib** - _eu.etaxonomy.taxeditor.remoting.cache.CdmServiceCacher_ : the class responsible for permanently caching CDM entities like terms. 

 * **eu.etaxonomy.taxeditor.cdmlib** - _eu.etaxonomy.taxeditor.session.CdmEntitySession_ : the class which represents a remoting session 

 * **eu.etaxonomy.taxeditor.cdmlib** - _eu.etaxonomy.taxeditor.session.CdmEntitySessionManager_ : the class which manages remoting sessions 

 * **eu.etaxonomy.taxeditor.cdmlib** - _eu.etaxonomy.taxeditor.session.ICdmEntitySessionEnabled_ : the interface which represents a session owner 

 ![](sessionarch.png)    



 ### Handler / Operations Architecture 

 The existing Eclipse RCP architecture has been extended with the main purpose of centralizing operation and post-operation logic, as well as centralising error management. 

 ![](handleroparch.png)   



 ### Data Change Service / Events / Listeners 

 The move to remoting requires a new mechanism for updating ui after updates to cdm entities.  


 The new design includes, 

 * **eu.etaxonomy.taxeditor.cdmlib** - _eu.etaxonomy.cdm.api.application.CdmDataChangeService_ : the class responsible for managing the data change listeners and events. 

 * **eu.etaxonomy.taxeditor.cdmlib** - _eu.etaxonomy.cdm.api.application.CdmChangeEvent_ : the class representing the cdm data change event. 

 * **eu.etaxonomy.taxeditor.cdmlib** - _eu.etaxonomy.cdm.api.application.ICdmChangeListener_ : the interface which should be implemented by classes - in particular Eclipse RCP UI elements (Viewers, Editors, etc)    - which display updated CDM entities. 



 ### Merge Strategies 

  There are two main strategies to be used when saving / updating cdm entities in remoting. 

 * **Single Entity Save / Update** : In the case of scenarios (Wizards, Sections, etc) where a single cdm entity is to be saved or updated, then the **cdmlib-services** - _eu.etaxonomy.cdm.api.service.ServiceBase.merge(T newInstance)/merge(List<T> detachedObjects)_ methods should be used. 

 * **Entity subGraph Save / Update** : In the case of scenarios (Editors, etc) where an entire entity subgraph is to be saved or updated, then the **cdmlib-services** - _eu.etaxonomy.cdm.api.service.ServiceBase.merge(T newInstance, boolean returnTransientEntity)/merge(List<T> detachedObjects, boolean returnTransientEntity)_ methods should be used. These methods update and return the transient (detached entity) to ensure that the already lazy-loaded subgraph entities remain accesible. The return type of MergeResult also contains a list of newly created persisted (id > 0) objects, if any, which are then updated in the session cache on the editor side. 



 ### Known Errors / Exceptions 

 This section provides a list of known errors or exceptions when developing in the remoting environment. 


 #### IllegalStateException 

  **message** : "An entity copy was already assigned to a different entity" 


  **reason** : The exception is thrown when a merge call is made on a object sub-graph in which at least two instances of the same entity class are loaded either 

 * in different sessions or 

 * one is loaded in a session an the other is not loaded in any session  


    This problem occurs usually when, 

 * sessions are not initialised / bound in the right order 

 * an exception is thrown when [[#EagerLazyLoading|eager lazy loading]] entities which may lead to a inconsistency in the active session. 

 * the initial service methods to load the entities are invoked before the session is bound 

  **solution** : To solve the problem  

 * check that the sessions are being initialised / bound in the right order using sessions view 

 * fix any errors occurring during [[#EagerLazyLoading|eager lazy loading]] 

 * make sure to always bind the session before any service call is invoked for that session 



 #### LazyInitializtionException 

  **message** : "could not initialize proxy - no Session" 


  **reason** : The exception is thrown when a service call (on the server-side) is trying to initialise proxies on a detached entity which has no session. This problem occurs usually when client side entity is passed as argument to a service method. 


  **solution** : To solve the problem make sure that service calls use uuids as arguments, which are then used to load the entities on the server side. 



 #### MySQLIntegrityConstraintViolationException 

  **message** : "Duplicate entry (uuid) for key (uuid)" 


  **reason** : The exception is thrown when a previously created cdm entity (id=0) reference is reused in the next merge call. 


  **solution** : To solve the problem check to ensure that the previously created cdm entity is updated (id > 0) and is the one that is reused. Using the <TBD:transient entity merge strategy> should usually fix the problem. 



 #### InvalidClassException 

  **message** : "org.hibernate.collection.internal.AbstractPersistentCollection; local class incompatible: stream classdesc serialVersionUID = 2742261122392386159, local class serialVersionUID = -7238232378593030571" (the reported serialVersionUID can be different though!) 


  **reason** : A dependent library of the cdmlib has been upgrated (most probably hibernate). Now the `serialVersionUID` which is generated on the fly differs from that which is entered in the special `AbstractPersistentCollection` in the taxeditor. 


  **solution** : To solve the problem adapt the `org.hibernate.collection.internal.AbstractPersistentCollection.serialVersionUID` in the editor subproject `eu.etaxonomy.taxeditor.cdmlib/src/main/java/org/hibernate/collection/internal/AbstractPersistentCollection.java` to the `serialVersionUID` as reported in the error message as `stream classdesc serialVersionUID`  



 ### Performance Tuning 

 Since the remoting version of the editor is essentially a web based application, it becomes important to optimise performance, specifically with respect to the amount-of-data vs number-of-remote-calls trade-off. This optimisation can be tuned in two ways, both of which use [[CdmEntityInitalization|property paths]], 

 * Initial Load Performance Tuning : This mechanism refers to the setting of required property paths for the first service call which loads the CDM entity or entities. An example of this can be seen in **eu.etaxonomy.taxeditor.cdmlib** - _eu.etaxonomy.taxeditor.editor.TaxonEditorInput_  

 * Lazy Load Performance Tuning : This mechanism refers to implementing the _getPropertyPathsMap_ method in the session owner (*eu.etaxonomy.taxeditor.cdmlib* - _eu.etaxonomy.taxeditor.session.TaxonEditorInput.ICdmEntitySessionEnabled_) interface. The method returns a Map of key objects linked to property paths, where the key objects could be either, 

   * the entity class object in the case of standard proxy objects or 

   * the field name of the Map of Collection object in the case of persistent collections. 



 ### Term Loading 

 Term loading refers to the application-level caching of CDM terms, so that the loaded terms can then be reused during the lifetime of the application. 

 In the context of remoting, term loading is implemented in two ways, 

 * On-demand Caching : where the terms are loaded on demand and then cached. The visual below describes the process where the method to load the term (_getTermByUuid_) in turn invokes the service cacher to load and cache the term. 

 ![](termloading.png)   

 * Http Invoker level caching : where a service method invocation itself can be cached by sub-classing **eu.etaxonomy.taxeditor.cdmlib** - _eu.etaxonomy.taxeditor.service.CdmServiceRequestExecutor_ and intercepting the relevant service method call to cache the results using the service cacher. An example of this can be seen in **eu.etaxonomy.taxeditor.cdmlib** - _eu.etaxonomy.taxeditor.service.TermServiceRequestExecutor_ where the _listByTermType_ method is cached. 

 

 ### Login 

 The remoting login mechanism is handled by three classes - namely, 

 * **eu.etaxonomy.taxeditor.store** - _eu.etaxonomy.taxeditor.ui.dialog.RemotingLoginDialog_ : which contains all the ui elements and logic for setting up a connection as well as connecting to a cdm server. 

 * **eu.etaxonomy.taxeditor.cdmlib** - _eu.etaxonomy.taxeditor.remoting.source.CdmServerInfo_ : which represents a target server which can be of four types, 

   * standard server : the standard deployed cdm server. 

   * local managed server : the weabpp server launched by the editor itself. 

   * local dev server : the webapp server launched within eclipse from the **cdmlib-remote-webapp** project. 

 * **eu.etaxonomy.taxeditor.cdmlib** - _eu.etaxonomy.taxeditor.remoting.source.CdmServerInfo.CdmInstanceInfo_ : which represents a cdm instance running on a cdm server. 




 ### Progress Monitor 

 Progress monitoring is an essential functionality in any UI architecture (including RCP), used in the case of long running methods which update a monitor object, which in turn provide status feedback to the user. With the implementation of remoting, monitoring of long running remote service calls becomes tricky, since the monitor object updated remotely can no longer be used to provide status feedback for the client. In this situation, it is becomes necessary poll the remote monitor at regular intervals and update the client monitor with the response.  


 An overview of the remoting progress monitor is seen below.  


 ![](progressmonitor.png)    


 An example of remoting progress monitoring can be seen in the ABCD Import functionality of the editor. The sequence of method calls to run an ABCD Import includes, 

 * The import starts with **eu.etaxonomy.taxeditor.store** - _eu.etaxonomy.taxeditor.io.wizard.AbcdImportWizard_ which calls the _runMoniteredOperation_ in the **eu.etaxonomy.taxeditor.store** - _eu.etaxonomy.taxeditor.io.ImportManager_ class. 

 * The ImportManager method in turn calls the _monitImportData_ in the **cdmlib-services** - _eu.etaxonomy.cdm.io.service.IIOService_ class which generates a new _RemotingProgressMonitor_ object, launches the import in a new _RemotingProgressMonitorThread_ and returns the uuid of the monitor. 

 * This uuid is used by the _ImportManager_ to call the _executeMoniteredOperation_ in the _AbstractUtility_ class which creates a client monitor, polls the remoting monitor and updates the client monitor with the response. 



 ### Helpful Hints 

 * **@Transient objects are not serialised** : Objects with @Transient that are transmitted over http-invoker in remoting are not serialised and should be initialised again on the editor side. 

 * **CDM Server Remoting switch** : Currently the spring profile 

 ~~~ 
   <beans profile="remoting"> 
     <import resource="classpath:/eu/etaxonomy/cdm/remoting-services.xml" /> 
   </beans> 
 ~~~ 
  set in the **cdmlib-remote-webapp_*/src/main/webapp/WEB-INF/cdmlib-remote-servlet.xml_ allows the cdm server to enable remoting by setting the *-Dspring.profiles.active=remoting** vm argument in the server jvm launch configuration. 



 ### General FAQ 


 ### How do I expose a new service to the taxonomic editor via remoting ? 

 For a new service _NewRemotingService_ implementing _INewRemotingService_, the following steps are required to expose the service via remoting, 


 CDM Server (cdmlib-services) side : 

 * Add the service to the **cdmlib-services** - _src/main/resources/eu.etaxonomy.cdm/httpInvokerServices.xml_ 

 ~~~ 
   ... 

   <bean id="httpNewRemotingService" 
     class="org.springframework.remoting.httpinvoker.HttpInvokerServiceExporter"> 
     <property name="service"> 
       <ref bean="newRemotingService" /> 
     </property> 
     <property name="serviceInterface"> 
       <value>eu.etaxonomy.cdm.api.service.INewRemotingService</value> 
     </property> 
   </bean> 

   ... 
 ~~~ 
 * Add the corresponding endpoint to the **cdmlib-services** - _src/main/resources/eu.etaxonomy.cdm/remoting-ervices.xml_ 

 ~~~ 
   <bean 
     class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping"> 
     <property name="order" value="0" /> 
     <property name="mappings"> 

       <!-- Needed for spring remoting with the http invoker --> 
       <!-- The configuration of the services is imported from httpInvokerServices.xml --> 
       <props> 
         <!-- services from cdmlib-services project --> 
         .... 

         <prop key="/remoting/newremoting.service">httpNewRemotingService</prop> 

         ... 
   </bean> 
 ~~~ 

 Taxonomic Editor side : 

 * Add a corresponding service getter method in the **cdmlib-services** - _eu.etaxonomy.cdm.api.application.ICdmApplicationConfiguration_ 

 ~~~ 
   ... 

   public INewRemotingService getNewRemotingService(); 

   ... 
 ~~~ 
 * Implement the above method in the **eu.etaxonomy.taxeditor.cdmlib** - _eu.etaxonomy.cdm.api.application.CdmApplicationRemoteConfiguration_ 

 ~~~ 
   ... 
  
   @Override 
   public INewRemotingService getReferenceService(){ 
       return (INewRemotingService) getService(INewRemotingService.class, "/remoting/newremoting.service", new CdmServiceRequestExecutor()); 
   } 

   ... 
 ~~~ 
 For details, refer to the [[#Remoting|Remoting]] section. 



 #### How do I integrate remoting sessions in ui elements ? 

 When integrating remoting sessions in ui elements (like Viewers, Navigators, Editors, etc) the steps include, 

 * Declare a cdm entity session variable  

 ~~~ 
 cdmEntitySession 
 ~~~ 
 * Initialise it with new session call  

 ~~~ 
 cdmEntitySession = CdmStore.getCurrentSessionManager().newSession(this, true) 
 ~~~ 
    where 'this' (i.e. the ui element) represents the session owner and should implement _ICdmEntitySessionEnabled_.  


    **NOTE :** The initialise call should be made BEFORE any remote service call is invoked. 

  Bind the session when the ui element is active (usually in the _setFocus()_ method) 

 ~~~ 
 cdmEntitySession.bind() 
 ~~~ 
 * Dispose of the session when the ui element is disposed (usually in the _dispose()_ method) 

 ~~~ 
 cdmEntitySession.dispose() 
 ~~~ 
  **NOTE :** In the specific case of Editors (which subclass _EditorPart_), it is the editors input object which should be the session owner. 



 #### What updates need to be done for the taxonomic editor following a model change ? 

 Refer to the [[#ModelChangeActions|Model Change Actions]] section. 


 #### The remote loading of CDM entities seems considerably slow. What can I do to speed things up ? 

 Refer to the [[#PerformanceTuning|Performance Tuning]] section. 



 #### What to do, if you want to use a new service method in the remoting editor 

 * use uuids as arguments 

 * add @Transactional(readOnly=false) 

 * for update / delete service calls return Update(Delete)Result objects with all related cdm entities 

 * if you create new entities, they are not cached until a merge call is made => don't hang on to their references 



 #### How can I check if remoting (HttpInvoker) is enabled in the cdm-server? 


 There is one HttpInvoker endpoint which can we accessed without authentication: 

 ~~~ 
 <CDM_SERVER_BASE_URL>/<INSTANCE>/remoting-public/metadata.service 
 ~~~ 
 in case remoting is enabled this service will respond with and HTTP 500 error and will show the following stacktracte: 


 ~~~ 
 java.io.EOFException 
	 at java.io.ObjectInputStream$PeekInputStream.readFully(ObjectInputStream.java:2325) 
	 at java.io.ObjectInputStream$BlockDataInputStream.readShort(ObjectInputStream.java:2794) 
	 at java.io.ObjectInputStream.readStreamHeader(ObjectInputStream.java:801) 
	 at java.io.ObjectInputStream.<init>(ObjectInputStream.java:299) 
	 at org.springframework.core.ConfigurableObjectInputStream.<init>(ConfigurableObjectInputStream.java:64) 
	 at org.springframework.remoting.rmi.CodebaseAwareObjectInputStream.<init>(CodebaseAwareObjectInputStream.java:97) 
 ~~~ 
 This response is normal behaviour when the service endpoint is requested with HTTP GET.  


 attachment:"cdm-server-remoting-debug.tar.gz" contains an attempt to create a suitable HTTP POST request using the curl command