Project

General

Profile

Taxonomic Editor Developers Guide

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

Development Environment

This section deals with the setup of the development environment for the Taxonomic Editor. The setup has been tested with Eclipse Neon (4.7) 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

  • If any of the software sites show error like 'Unable to locate ..', select all software sites and hit Reload. This will compute the dependencies of the various plugins and retrieve them to give a result which looks like

  • If there are still errors (e.g. nebula composite table) try removing and re-adding the update site.

rcp.target.png

Warning : If the errors were not resolved try restarting Eclipse and redo the above two steps.

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 Neon 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.

target_platform.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.

  • Open eu.etaxonomy.taxeditor.product in the eu.etaxonomy.taxeditor plugin and choose Launch an Eclipse Application to launch the product. This will create a new launch configurations for Run / Debug.

Eclipse maven plugin (m2)

If you did not import the project already as Maven project you need to configure the taxeditor project differently:

After the Target RCP Environment (see above) is set and without errors, right click on the eu.etaxonomy.taxeditor.cdmlib project and convert it to a maven project:

eclipse-m2-configure-taxeditor.png

Note: A dialog pops up to import the missing maven connectors saying that a mapping for antrun is missing. Just install all connectors that are available. The problem with antrun will then be solved by downloading and importing https://dev.e-taxonomy.eu/gitweb/cdmlib.git/blob_plain/refs/heads/master:/lifecycle-mapping-metadata.xml in the preferences under Maven->Lifecycle Mappings->Change mapping file location

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. Note: This can also be set in the taxeditor general preferences

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 .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 .cdmLibrary/cdmlib-remote properties file by adding
   cdm.datasource=local-cdmTest 

or in the above run/debug configuration by adding

   -Dcdm.datasource=local-cdmTest 

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.

Troubleshooting
Linux: The test crashes due to a segmentation fault in libsoup-2.4.so.1

This type of crash produces a log message like:

A fatal error has been detected by the Java Runtime Environment:
#
# SIGSEGV (0xb) at pc=0x0000003119a6dab1, pid=9245, tid=140539766241024
#
# JRE version: Java(TM) SE Runtime Environment (7.0_45-b18) (build 1.7.0_45-b18)
# Java VM: Java HotSpot(TM) 64-Bit Server VM (24.45-b08 mixed mode linux-amd64 compressed oops)
# Problematic frame:
# C [libsoup-2.4.so.1+0x6dab1] soup_session_feature_detach+0x11
#

The blog post https://sottamjr.blogspot.de/2013/12/java-mission-control-jmc-crashing.html offers a solution to that problem.
You can easily apply this fix directly to the launcher configuration of JUnit Plugin Test to be run.
Add the following two VM Arguments to the launcher:

-Dorg.eclipse.swt.browser.DefaultType=mozilla
-Dorg.eclipse.swt.browser.XULRunnerPath=/usr/lib64/xulrunner

If you are till having problems, you may want to also apply the fix described in http://cybertaxonomy.eu/taxeditor/troubleshooting.html#ubuntu_gtk2_eclipse_rcp_crash

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 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 Eclipse: JUnit Plugin Tests / Server and for Maven refer to Maven: JUnit Plugin Tests / Server.

Deployment

P2 Updates

Eclipse RCP provides a mechanism for self updates via the Equinox/p2 Self-Update 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 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 maven goals to be run for generating the product bundled with the jre.

NOTE : This configuration will change with the resolution of ticket 5430

Continuous Integration

The jenkins jobs related to the Taxonomic editor include,

  • taxeditor-INTEGRATION : which packages the 'develop' branch and deploys both the final product and the p2 updates.

  • 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 : which packages the chosen branch and deploys both the final product and the p2 updates to the chosen update site directory.

  • 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,

Hotfix Jobs

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

Post Release / Hotfix

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=

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= 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

  • (More or less) 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.

NOTE (by AM): I had problems running with maven. Instead I ran the main class directly from the IDE. Also I adapted the hibernate.cfg.xml such that I use a separate connection provider class (CdmModelCacherConnectionProvider). The later class needs to be adapted if run from another account then mine.
I also added ImplicitNamingStrategyComponentPathImpl to hibernate.cfg.xml as this parameter is usually provided by Spring.
Therefore you can not just copy hibernate.cfg.xml but only the mapping and other relevant parts should be copied.

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 of Spring Remoting, HttpInvoker 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 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 (Remoting Sessions Architecture)

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 (Handler / Operations Architecture)

Controllers / Service Endpoints

The HTTP Invoker remoting solution uses two sets of services whereas the one set is accessible without authentication. The other set of services is restricted (see also How-do-I-integrate-remoting-sessions-in-ui-elements-):

  • /remoting-public/ accessible without authentication
    • /remoting-public/metadata.service
    • /remoting-public/user.service
  • /remoting/ authentication required

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 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 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 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 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 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 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 (Term Loading)

  • 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 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 (deprecated with the switch to e4): 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 Model Change Actions section.

TaxonomicEditorDevelopersGuide#Model-Change-Actions

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

Refer to the 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.

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

testing.png View (141 KB) Cherian Mathew, 09/23/2015 10:59 AM

eagerlazyloading.png View (108 KB) Cherian Mathew, 10/12/2015 05:08 PM

remotingconfig.png View (156 KB) Cherian Mathew, 11/02/2015 04:22 PM

progressmonitor.png View (113 KB) Cherian Mathew, 11/18/2015 02:36 PM

editor-luna-set-target.png View (71.3 KB) Cherian Mathew, 11/18/2015 03:25 PM

editor-luna-rcp-target.png View (78.7 KB) Cherian Mathew, 11/18/2015 03:25 PM

handleroparch.png View - Handler / Operations Architecture (88.8 KB) Cherian Mathew, 11/30/2015 12:36 PM

sessionarch.png View - Remoting Sessions Architecture (100 KB) Cherian Mathew, 11/30/2015 12:47 PM

termloading.png View - Term Loading (59.5 KB) Cherian Mathew, 12/02/2015 11:09 AM

cdm-server-remoting-debug.tar.gz (650 Bytes) Andreas Kohlbecker, 02/23/2016 03:21 PM

eclipse-m2-configure-taxeditor.png View (149 KB) Andreas Kohlbecker, 02/07/2018 03:37 PM

target_platform.png View (91.7 KB) Patrick Plitzner, 02/12/2018 10:13 AM

rcp.target.png View (75.8 KB) Patrick Plitzner, 02/12/2018 10:18 AM

picture745-1.png View (10.4 KB) Patrick Plitzner, 03/18/2019 09:35 AM

Add picture from clipboard (Maximum size: 40 MB)