Migration to FlowUI

Unfortunately this is a big problem… Let’s hope the Jmix team finds some solution for such a smooth migration.

Hi all,

Until there is any “official” migration guide, I’d recommend trying this simple instruction:

  • In your current project, create a new branch: git checkout -b flowui
  • Open the project in the IDE
  • Create new FlowUI project with the same name and base package
  • Copy root files from the new project:
    .gitignore
    .npmrc
    .pnpmfile.cjs
    build.gradle
    package.json
    tsconfig.json
    types.d.ts
    vite.config.ts
  • Copy frontend dir from new project
  • Remove screen package (java and resources)
  • Copy view package (java and resources) from new project
  • Copy META-INF resources dir from new project
  • In application.properties
    • Remove jmix.ui props
    • Copy jmix.flowui, ui, vaadin props from new project
  • Replace the whole contents of menu.xml
  • Remove {base-package}.screen messages
  • Copy {base-package}.view and {base-package}/menu.application.title messages from new project
  • Remove resource/theme dir
  • In root changelog.xml remove /io/jmix/securityoauth2/liquibase/changelog.xml and /io/jmix/uidata/liquibase/changelog.xml
  • Replace the whole contents of FullAccessRole by opening it in external editor (it’s read-only in a Jmix project)
  • Copy UiMinimalRole from new project
  • Replace @ScreenPolicy and @MenuPolicy annotations in other roles
  • Add to main app class:
    @Push  
    @Theme(value = "{project-name}")  
    @PWA(name = "{project-name}", shortName = "{project-name}")
    class ... implements AppShellConfigurator	
    
  • Build → Build Project
  • Fix compilation problems if any
  • Generate CRUD views for entities
  • Add required UI logic :stuck_out_tongue_winking_eye:
3 Likes

Thank you, @krivopustov! Your list of steps is a good starting point, which at least helps to have a basic idea on how to start such a migration.

Maybe you could at some point make this even part of the official documentation? I guess with the flow UI integration being more mature more and more teams will think about migrating their apps to the new UI and this topic might come up more frequently.

1 Like

Sure, we’ll do it when the situation with FlowUI becomes more stable.

1 Like

Any new word on this rather important topic? There was a recent announcement about the split of Jmix versions 1.x / 2.x with Classic UI only and Flow UI only … further orphaning large Jmix projects which are on Classic UI because that’s all that existed when these projects were begun.

This is another nightmare situation similar to the CUBA 6 → 7 situation (I wasn’t around during those days, but by the number of people that stayed on 6 vs. 7 I have to assume that was another nightmare migration scenario), then the CUBA → Jmix migration was another nightmare. And now we’re repeating it yet again?

There really needs to be a better way; orphaning your users is just not a good thing.

1 Like

After a short experiment this AM, I see even more that at least a “bootstrap” migration from Classic → Flow should be provided and would not be terrible to implement. For example, here is a dead-simple CRUD type screen, the type that there are dozens of in most large applications. (Descriptor only).

CLASSIC:

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<window xmlns="http://jmix.io/schema/ui/window" xmlns:dynattr="http://jmix.io/schema/dynattr/ui"
         caption="msg://editorCaption"
        focusComponent="form"
>
    <data>
        <instance id="physicianTypeDc"
                  class="com.medflex.medflexj.entity.physician.PhysicianType"
                  fetchPlan="_local">
            <loader/>
        </instance>
    </data>
    <dialogMode height="600"
                width="800"/>
    <layout expand="editActions" spacing="true">
        <form id="form" dataContainer="physicianTypeDc">
            <column width="250px">
                <textField id="nameField" property="name"/>
                <checkBox id="isPrescribingField" caption="msg://isPrescribingField.caption"
                          dataContainer="physicianTypeDc" property="isPrescribing"/>
            </column>
        </form>
        <hbox id="editActions" spacing="true">
            <button action="windowCommitAndClose"/>
            <button action="windowClose"/>
        </hbox>
    </layout>
    <facets>
        <dataLoadCoordinator auto="true"/>
        <dynattr:dynamicAttributes/>
    </facets>
</window>

FLOW:

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<view xmlns="http://jmix.io/schema/flowui/view"
      title="msg://physicianTypeDetailView.title"
      focusComponent="form">
    <data>
        <instance id="physicianTypeDc"
                  class="com.medflex.mfflow.entity.physician.PhysicianType">
            <fetchPlan extends="_base"/>
            <loader/>
        </instance>
    </data>
    <facets>
        <dataLoadCoordinator auto="true"/>
    </facets>
    <actions>
        <action id="saveAction" type="detail_saveClose"/>
        <action id="closeAction" type="detail_close"/>
    </actions>
    <layout>
        <formLayout id="form" dataContainer="physicianTypeDc">
            <textField id="nameField" property="name"/>
            <textField id="legacyCodeField" property="legacyCode"/>
            <checkbox id="isPrescribingField" property="isPrescribing"/>
        </formLayout>
        <hbox id="detailActions">
            <button id="saveAndCloseBtn" action="saveAction"/>
            <button id="closeBtn" action="closeAction"/>
        </hbox>
    </layout>
</view>

This isn’t much more than a search-and-replace type of affair, with some reordering of the elements.

A more complex screen isn’t much different. There are some differences such as dateField becoming datePicker and certain attributes being renamed such as optionsContainer becoming itemsContainer and caption becoming label and so on.

This is not difficult and would enable much more easy transition from Classic → Flow for users with large applications.

As promised, we will include Classic UI → Flow UI migration recommendations in the documentation when version 2.0 is released.

Regarding the whole situation with 1.x - 2.x, it wasn’t our idea to rename javax to jakarta and generate the wave of incompatible updates. The article explains why we cannot include classic UI in 2.0: Extended Support for Classic UI – Jmix
And I don’t think that free support for 1.x till 2028 sounds like orphaning users.

So what do you see as a better way?

A reliable automatic migration Classic → Flow is impossible due to lots of differences. And our experience with CUBA → Jmix migrator tell us that any semi-complete solution doesn’t live up to expectations and users are mostly not satisfied, while developers put a lot of effort into the tool.

Perhaps a better solution will be providing a commercial service for migrating complex applications. Then the result will be predictable and all expectations will be met.

That is a good point. :frowning:

That is true - CUBA → Jmix migrator was awful, though mostly because most of us assumed it was a complete, one-and-done thing that would “just work.” Which proved impossible from both ends.

I was posting at the same time you were - in my post above I showed Classic and Flow versions of a very simple screen - it’s mostly some text changes and some reordering.

I don’t know. I think creating a “bootstrap” migrator the does that very basic-bare-bones text changes and such and calling it a “bootstrap” or similar name that makes it clear you’re not “done” once that’s run (to avoid false hope, and also avoid complaints that it’s not complete) would still be a great help as at least it would probably be “mostly done” on the bare-bones autogenned CRUD screens and give us all a solid start on the more complex ones. I’m just talking about descriptor migration, obviously.

Agree that proper choosing of names is very important. If the “awful” migrator would be called a “bootstrap” feature, perhaps it wouldn’t be so awful. Duly noted.

As for your example with generated CRUD screens in Classic/Flow UI, what is the point to migrate them if you could just regenerate them from entities, including controllers? So if your project is 70% CRUD, you’ll get 70% migrated almost instantly. Also, you could create and use your own templates for the generation.

And I apologize for the harsh wording - in our case, we’re a small team (just 4 of us in the entire company - and I am the sole active programmer!) working on converting a giant application with a long history under pressure of market competition. I know the team worked extremely hard on the CUBA → Jmix migrator. Expectations were high, unfortunately.

Well, in our case, with a tiny team (I am the sole active programmer), going in and generating each specific one and then hand-placing it into the menu structure (we do not just have every single screen in one monolithic menu; it is categorized for user ease) represents a significant bit of time. I believe that could be done by a “bootstrap” migrator coded once for the entire Jmix user base, a great boon and help.

Not to mention the other steps mentioned in your previously posted “rough outline of how do to it” - all the “copy this stuff to here, copy that stuff to there” etc steps, could also be automated by this “bootstrapper.”

Any time savings is a great boon. Many users just went through the CUBA → Jmix phase, possibly at significant cost (my company of course ended up contracting with Haulmont to help with it for instance).

Just to show what I mean about menu, etc:

maint-menu-1
maint-menu-2

No problem. Actually the fact that a sole developer can create and maintain a big application is a great compliment to Jmix.

If I understand you right, you don’t mind regenerating CRUD screens from scratch, you just want to do it automatically for all entities and keep the menu structure? That sounds good to me because it doesn’t require much heuristics and should produce a working application. The initial steps for creating proper project structure and copying backend code are also quite easy to automate.

What I would really like to avoid is to make a tool which produces non-working code in most cases.

2 Likes

Absolutely true! CUBA and Jmix are incredible products, 100%!

Eh, some type of bare-bones very rough conversion would be helpful. In the simplest case, like I showed with the descriptor comparison above, it’s just changing a few names and re-arranging some positions in the XML.

Any further thoughts here? :slight_smile:

We’ll certainly think about simplifying migration, but a bit later. First we need to launch 2.0 and important add-ons with Flow UI.

2 Likes

@krivopustov - Any word here? It’s been a year. We are still on 1.5 because our application is huge (I’m sure you’ve seen it) and the process of 1.5 → 2.0 is basically “start over.”

I’d recommend watching this guide:

@krivopustov - It is a good guide series, but guys, really, you can do better.

CUBA 6 to 7 must have been a nightmare for people. (Back in the CUBA days many stayed on 6…there must have been a reason).

CUBA → Jmix was a nightmare. That ended up costing us thousands of dollars and about a year of time. (we paid you to migrate for us in the end.).

Then very soon after, there was Jmix 1 → 2. Another nightmare.

There is a pattern here. :frowning:

You can do better! :slight_smile: I know it’s a lot of work, but the “bootstrap” migrator we discussed over a year ago is something you could produce. Just something to automate the steps outlined by Mario plus a copying of screens and such, and adjusting what can be adjusted.

For example if you know that something was named “X” in 1.x and it’s now named “Y” that’s just a search and replace operation. There are many things like this that you could automate.

Jmix’s strength is that it allows small teams (like mine) to do truly, truly amazing things. But that’s also a weakness. Because such small teams (i.e., a team of one in many cases) can do such amazing things… we WILL do those things with tiny teams. But then when something like the 1 → 2 path comes along, that small team has a gigantic workload because - and here’s the truth - the migrations are far more difficult and labor-intensive than the actual application development! However, some or even “much” of that work is “grunt work” which could be (semi) easily automated.

(If you guys still have a copy of our application from when we contracted you to migrate CUBA → Jmix… Give a try at migrating it to Jmix 2.x. Perhaps that will give you perspective on it.)

I won’t even say that I agree very much with @modemmisuser . :slightly_smiling_face:
@krivopustov , on the other side of the Earth, man talks about the same thing that we talked about with you and with @v.fadeev :

  • maybe you are planning to deploy the product towards only large teams with a large Java/Spring Boot expertise?
  • migration is documented with gaps and it is more difficult than ever
  • the documentation has become less clear and more “sketchy”
  • Jmix entry has become higher than Cuba entry

We were migrating Cuba 6 - > Cuba 7 and here I disagree with Jon.

It was easy.

Then I was ready that it would take us 1 month, but it took us 2-3 days and the application was already working on the new platform.
Then we smoothly changed the code to use the new API and did it in parallel with the planned development of the application.
Therefore, you can definitely make migration less painful. I know: -)

Now we are completing the migration of Cuba 7 - > Jmix 1.5 and it took us almost 5 months when we were engaged in Migration only and forgot about feature development.
About half of the time was spent on what is simply not described in the migration documentation.
I will try not to think about Jmix 1.5 migration - > Jmix 2.0 for another two years: -)

If for many the migration of Cuba 6 - > Cuba 7 turned out to be difficult, then the migration to Jmix for them will cost no less (or even more) than to develop applications anew.
In this case, will they develop it on Jmix or change the platform?

A huge plus of Cuba/Jmix is that a working application solution can be made quickly by a small team without Java/Spring expertise. And the team will focus on Applied Tasks.
But the saved time and money they will be “eaten” as soon as you need to migrate to the new version.

For many micro-commands, this will negate the merits of Jmix.
Pretty sure small teams don’t make you a lot of money. But there are many such teams. :slight_smile:
They create the popularity of the product and help make it even more universal.

1 Like

Absolutely. The migration would be effortless if we wouldn’t update the underlying technologies (as was the case in CUBA 6 → 7 update).

But you would end up with unsupported stack, security vulnerabilities and outdated approaches.