Hi all
I know this could be a quite old topic to touch, but I’m currently migrating a legacy CUBA application, with a quite deep custom add-on dependency tree, to Jmix 1 and since I didn’t find any step-by-step guide on how to do the task in the subject of this post (there are a couple of posts in the forum, though), I wrote it myself. If there still are out in the wild legacy applications similar to ours that need to be migrated, I hope this post can help their maintainers.
Glossary
- OP: Original project, the CUBA application the migration is done from
- MP: Migrated project, the Jmix 1 application migrated from OP
- ADDP: Add-on project, the final Jmix 1 add-on project
- APP: Application project, the empty Jmix 1 application to test ADDP
Steps
-
If you don’t have any database backup for the original CUBA Application (aka original project or OP), do it now, then restore it inside a new schema.
[suggested] Use as schema name the same original one plus the prefix “-jmix”.
-
Follow main migration guide, creating a migrated project (aka MP) setting in the target project the Main Data Store to reference the new schema created in point 1.
- If you are going to use a seperate Add-On for user authentication, remove all classes and screens referencing the new User entity, including:
-
DatabaseUserRepository
-
FullAccessRole
-
content of 010-init-user.xml
-
User itself
-
[optional] MainScreen
-
[optional] LoginScreen
-
Check whether liquibase scripts contain all needed ddl and if they are correctly configured context-wise (
cuba/migrated) - pay attention to create table statements (check if they are inside the changelog formigratedcontext)If no create table statements were created (which is the case if you just followed the context
cubapath), changemain.liquibase.contextstomigratedand Recreate database, then Generate Liquibase changelog; addcontextattribute to allchangeSetsetting it tomigrated. Don’t forget to changemain.liquibase.contextsback tocuba.[suggested] Move ddl statements generated this way to a different file in the Liquibase root with a name like
020-init-<project-id>.xmlinstead of the date-time folder and name. -
Check that the
application.propertiesfile contains the following declarations:
-
main.liquibase.contexts = cuba
main.datasource.studio.liquibase.exclude-prefixes=audit_,email_,sys_,ui_,sec_role,sec_group,sec_group_hierarchy,sec_user_role,sec_permission,sec_constraint,sec_localized_constraint_msg,sec_session_attr,sec_user_setting,sec_user_substitution,sec_logged_entity,sec_logged_attr,sec_entity_log,sec_filter,sec_session_log
- If the OP contains custom javascript components, there is a substantial chance that the migration didn't properly put the .js files in the MP (and the details don't show up in MigrationResult.md). Create the same folder structure inside `src\main\resources\` of the MP and copy the .js files inside it.
- Create a new Jmix project (aka add-on project or ADDP) with the following attributes:
- Jmix version: 1.6.2+ (but still Jmix 1, of course)
- Project SDK: 17
- Template: Add-on
- Project name: Free - [suggested] The same as MP, as long as it doesn’t overwrite it
- Project location: Free - [suggested] The same as MP, with prefix “-addon”
- Base package: The same as MP
- Project id: The same as MP
-
Copy all classes and resources from the MP to
<project id>/src/mainfolder of the ADDP, using the same exact folder structure. Remove the<Project id>Applicationclass (the one with the annotation@SpringBootApplication), renameapplication.propertiestomodule.propertiesand pay attention that it is inside<project-id>\src\main\resources\<base-package>\<project-id>- if not, move it there (most likely you will have to remove an already existingmodule.propertiesfile before doing this). Copy all the dependencies frombuild.gradleof the MP to the<project-id>.gradlecorresponding section. Don’t touch anything inside<project id>-starterfolder, unless there were some errors to fix during the creation of the ADDP. -
Set up the correct repositories inside
build.gradle, thenclean build publishit.[suggested] Use variables at the beginning of the gradle script to manage urls, credentials and so on. For example:
ext.version = '<version>'
ext.isSnapshot = !project.hasProperty('isSnapshot') || Boolean.parseBoolean(project.property('isSnapshot').toString())
ext.baseRepoUrl = "https://<host>:<port>/<folder>"
ext.repoUser = project.hasProperty('repoUser') ? project.property('repoUser') : "<your repo username>"
ext.repoPassword = project.hasProperty('repoPassword') ? project.property('repoPassword') : "<your repo password>"
group = '<group>'
version = "${version}${isSnapshot ? "-SNAPSHOT" : ""}"
...
repositories {
maven {
url "${baseRepoUrl}/maven-public/"
credentials {
username = repoUser
password = repoPassword
}
}
mavenCentral()
maven {
url 'https://global.repo.jmix.io/repository/public'
}
mavenLocal()
}
...
publishing {
repositories {
maven {
name = "<name>"
url = baseRepoUrl + (isSnapshot ? '/maven-snapshots/' : '/maven-releases/')
credentials {
username = repoUser
password = repoPassword
}
}
}
publications {
javaMaven(MavenPublication) {
artifactId = archName
from components.java
}
}
}
Replace all the <> variables accordingly
-
To test that the Add-On work as intended, create a new empty CUBA project and migrate it to Jmix (aka application project or APP) following the same exact steps described in point 2, then add the ADDP coordinates to the
build.gradlefile of APP. Create a new schema on the database and restore the backup made in point 1, then set the Main Data Store of APP to reference this new schema. Double check that APP uses the correct JDK (17) to avoid issues both at compile time and at runtime. Launch the application and test the Add-On functions.[suggested] Create a dummy project and re-use it when repeating the migration process for other Add-Ons, by simply restoring the desired database and changing the Add-On coordinates inside the
build.gradlefile of APP