Cloud Software Group, Inc. EBX®
Documentation > Migration Guide
Navigation mode Documentation > Migration Guide

# Step 1: Adapting custom code

## Overview

As a developer, your role to support migration is to ensure that any custom code used in your EBX® implementation compiles against the new EBX® binaries and is capable of successful deployment. This task requires that you understand the differences in the new EBX® 6 architecture and how it impacts performance of existing custom Java code. You should also familiarize yourself with the information regarding backwards compatibility contained in the TIBCO EBX® Release Notes.

Begin the process of updating your custom code by reviewing the new architecture's impact on custom code. Then follow the steps in Adapt code and test migration. After successful completion of the test phase, you will have:

- Adjusted and tested your code.

- Made changes in your data models and projects required to successfully test migration in your local environment.

- Generated new binaries capable of deployment and testing in the pre-production environment.

## New architecture impact on custom code performance

The new scalable architecture can impact the performance of custom Java code. Some scenarios that worked well before might require adjustments. In particular, focus on replacing or optimizing the following:

Repeated lookup by primary key | Previously, when the cache in our custom EBX® in-memory indexes could contain an entire table's data, it was cheap to access records using random table lookups. This type of access must now be rewritten to take advantage of the new SQL features. Take for example Java code that performed a nested loop join where a `RequestResult` from table A was iterated on and the `osd:tableRef` was looked up in table B. You should now implement a `Query` that uses an SQL join to handle the lookup.
Repeatedly creating similar requests | EBX® now embeds the Apache Calcite framework to optimize the submitted instances of `Query` and `Request`. Query optimization does have a cost; it is generally low and paid back when compared to executing a non-optimized query. However, it can create significant overhead when a loop generates numerous queries that differ by only a single parameter. In this case, use of parameterized requests (see `Request.setXPathParameter`) or parameterized queries (see `Query.setParameter`) is optimal.
Programmatic access rules | Programmatic access rules implement the Java interface `AccessRule`. On query execution, setting a rule on a table implies execution of the method `getPermission` for each record. This negates the advantages of optimizing against an index. Wherever possible, you should replace these programmatic access rules with the new scripted record permission rules.
Programmatic labels | Programmatic labels implement the Java interfaces `TableRefDisplay`, `UILabelRenderer` and `ConstraintEnumeration`. On query execution, setting a rule on a foreign key field implies execution of the method `displayOccurrence` for each record. This negates the advantages of optimizing against an index. Wherever possible, use a pattern string instead.
Programmatic filters | Programmatic filters implement the Java interface `AdaptationFilter`. On query execution, using this filter implies execution of the method `accept` for each record. This negates the advantages of optimizing against an index. Where possible, replace programmatic filters with the new SQL queries.
Constraints with unknown dependencies | Avoid constraints with unknown dependencies on large datasets, as they are checked on each validation request. See Data validation for more information.
Unnecessary index refresh | To improve transaction performance (Java implementations of `Procedure` and also of `TableTrigger`), any unnecessary index refresh should be avoided. For more information, see Unnecessary index refresh.
Inherited fields | As explained in the Search limitations, inherited fields cannot benefit from the new index optimizations. As a consequence all operations (querying, validation, data comparison, etc.) that will be performed on inherited fields will be slower compared to versions prior to EBX® 6. It is strongly advised to not use inherited fields to avoid performance issues. Wherever possible, depending of the use case, it is recommendable to convert these fields into linked fields or to substitute the behavior of inherited fields by simulating inheritance using triggers for instance.

## Adapt code and test migration

It is important that prior to testing migration, you remove all JAR and WAR files related to EBX® 5 from your environment.

1. Repository preparation:

   The following lists high-level tasks for preparing your local repository for your development environment. When preparing a pre-production or production repository for migration, or for more details on repository cleanup tasks mentioned in the following steps, see Step 2: Preparing the repository.

   1. Backup your existing repository.

   2. Start EBX® and ensure all data models compile without errors.

   3. Ensure that no data model dependencies on discontinued add-ons exist. See Changes to supported add-ons for more information.

   4. Clean dataspaces and workflows. This step is optional. However, note that any closed dataspaces are deleted during migration. Re-open any dataspace you want to keep. This step is more beneficial for larger repositories where large numbers of dataspaces could lead to longer migration times.

   5. Ensure the URL policy conforms to 6.x requirements. Navigate to Administration > User interface > User interface configuration > Advanced perspective > Interface configuration > URL Policy and revert any existing settings. To update the URL computing configuration, you can edit the `ebx.properties` file. See URLs computing for more information.

   6. Shutdown and then backup your clean repository.

2. Code preparation:

   1. Download EBX® 6 binaries from TIBCO eDelivery (an account is mandatory in order to access eDelivery, please contact the support team to request one) and deploy the following JARs in your local environment (located in `<your download directory>/ebx.software/lib`):

      - When migrating to EBX® 6.0.x:

        - For EBX® APIs: `ebx.jar`

        - To support the new compression algorithm: `ebx-lz4.jar`

      - When migrating to EBX® 6.x:

        - To support the new compression algorithm: `ebx-lz4.jar`

        - For EBX® Java APIs: `ebx-api.jar`

        - For third-party Java APIs: `ebx-resources-api.jar`

   2. Review the following to ensure any custom code complies with new recommendations and requirements:

      - New architecture impact on custom code performance

      - Release Notes > Backward compatibility sections.

      - Java API changes

   3. Recompile any custom libraries or webapps.

3. Initiate auto migration by starting your local server. The process should terminate successfully. Look for the following log entry in the `kernel.log` file: `EBX® Started and Initialized`.

   The following are common issues that can problems:

   - Libraries not compiled using EBX® 6. If this is the case, EBX® throws the following exception: `java.lang.IncompatibleClassChangeError`.

   - Data model errors. If any errors were left unresolved, the migration process is automatically terminated.

   - Compile error in the project if the project isn't built correctly.

Once migration completes successfully in your local environment, you can deploy and test in a pre-production environment with a larger repository. However, when testing in a pre-production environment, it is imperative to follow the process outlined in Step 2: Preparing the repository to prepare the repository prior to starting the application server.

Documentation > Migration Guide