๐Ÿง‘โ€๐Ÿ’ป๐Ÿ John's Gemini capsule ๐Ÿฏ

..........................................................................

=> ๐Ÿ›– home page | ๐Ÿšง now page | ๐Ÿ“ notebook | ๐Ÿ“œ blogroll | ๐Ÿง‘โ€๐Ÿ’ป about me

..........................................................................

Sane app architecture the Java way

Disclaimer: I restored this post after having deleted it. Probably not going to make anything work this way, but it is a nice study I think.

So let's start. Lots could be said. Let it keep short: I don't like web apps. The web is meant to transfer information. Browser are meant do display information, not ads nor apps.

Apps should be beautiful and at least behave native. You have to make compromises on cross platform solutions, but native GUI kits are important. (Qt is ugly.)

While I like to code, I have got few time, I'm lazy and I don't like to write boilerplate code.

The heart of every application are data structures. Programming languages are secondary. They just need to be easy, fun and understandable to work with (ok, quite some requirements, I admit).

So I begin with designing database structures and generating code templates from there.

From the great time of Apple's WebObjects there is a free port (or reimplementation) of the good old Enterprise Objects Frameworks (EOF), which is Apache Cayenne. While it is Java as well (just like the posterior WebObjects), it's maintained up to today (praise to Andrus Adamchik) and integrates into modern Java web apps without being as bloated as Spring et. al.

Fast prototyping

Using Apache Cayenne and it's great CayenneModeler one should be able to quickly prototype a simple desktop app quite well.

This could look like this:

                     โ•ญโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ•ฎ
                     โ”‚Database:         โ”‚
                     โ”‚    PostgreSQL    โ”‚
                     โ”‚                  โ”‚
                     โ•ฐโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ–ฒโ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ•ฏ
                   โ•”โ•โ•โ•โ•โ•โ•โ•โ•โ•โ”‚โ•โ•โ•โ”‚โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•—
                   โ•‘ โ•ญโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ–ผโ”€โ”€โ”€โ”€โ”€โ”€โ”                            โ•‘
                   โ•‘ โ”‚                  โ”‚                SWT         โ•‘
           โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค  Apache Cayenne  โ”‚                            โ•‘
           โ”‚       โ•‘ โ”‚                  โ”‚                Java App    โ•‘
Code       โ”‚       โ•‘ โ•ฐโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ•ฏ                            โ•‘
generation โ”‚       โ•‘                     M  V  V  M                  โ•‘
           โ”‚       โ•‘ โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”     โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”   โ•‘
           โ”‚       โ•‘ โ”‚                  โ”‚     โ”‚                  โ”‚   โ•‘
           โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ–บ  Models          โ”‚     โ”‚ GUI: SWT / JFace โ”‚   โ•‘
                   โ•‘ โ”‚                  โ”‚     โ”‚                  โ”‚   โ•‘
                   โ•‘ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜     โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜   โ•‘
                   โ•‘                                                 โ•‘
                   โ•šโ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•

GUI modeling for SWT is done using Eclipse WindowBuilder.

=> DBeaver - Manage any SQL database (PostgreSQL in this case) | Apache Cayenne | Apache Cayenne: Getting started guide. See how to use Cayenne Modeler to model data structures (you may you use DBeaver and the database first approach as well) | Personal website of Andrus Adamchik | Wikipedia: The Modelโ€“viewโ€“viewmodel pattern | GitHub: Implementation of the MVVM pattern for JFace | Eclipse WindowBuilder

Sane app design

For prototyping you maybe could even use SQLite instead of PostgreSQL. But chances are high you need to change lots of the database layout for later migration.

Running an app directly connected to a networked database solution like PostgreSQL is no solution for more than personal use deployments of course.

Also you won't be able to run a Java SWT app on many devices nowadays. The biggest market share is mobile. So we need to design an interface for mobile apps. While Cayenne supported Remote Object Persistence (ROP) via Hessian protocol until version 4.2 it is deprecated by that version. And of course you would use a RESTful API for this purpose these days.

Adopting more solutions you get something like this:

         โ”Œโ•ถโ•ถโ•ถโ•ถโ•ถโ•ถโ•ถโ•ถโ•ถโ•ถโ•ถโ•ถโ•ถโ•ถโ•ถโ•ถโ•ถโ•ถโ•ถโ•ถโ•ถโ•ถโ•ถโ•ถโ•ถโ•ถโ•ถโ•ถโ•ถโ•ถโ•ถโ•ถโ•ถโ•ถโ•ถโ•ถโ•ถโ•ถโ•ถโ•ถโ•ถโ•ถโ•ถโ•ถโ•ถโ•ถโ•ถโ•ถโ•ถโ•ถโ•ถโ•ถโ•ถโ•ถโ•ถโ•ถโ•ถโ•ถโ•ถโ•ถโ•ถโ•ถโ•ถโ•ถโ•ถโ•ถโ•ถโ•ถโ•ถโ•ถโ•ถโ•ถโ•ถโ”
         โ•Ž    โ•ญโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ•ฎ                                     +-+         โ•Ž
         โ•Ž    โ”‚Database:         โ”‚                                     |S|         โ•Ž
         โ•Ž    โ”‚    PostgreSQL    โ”‚                                     +-+         โ•Ž
         โ•Ž    โ”‚                  โ”‚                                     +-+         โ•Ž
         โ•Ž    โ•ฐโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ–ฒโ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ•ฏ                                     |e|         โ•Ž
         โ•Ž  โ•”โ•โ•โ•โ•โ•โ•โ•โ•โ•โ”‚โ•โ•โ•โ”‚โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•—        +-+         โ•Ž
         โ•Ž  โ•‘ โ•ญโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ–ผโ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ•ถโ•ถโ•ถโ•ถโ•ถโ•ถโ•ถโ•ถโ”                โ•‘        +-+         โ•Ž
         โ•Ž  โ•‘ โ”‚                  โ”‚  โ•Ž   B    โ•Ž    Java App    โ•‘        |r|         โ•Ž
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค  Apache Cayenne  โ”‚  โ•Ž   o    โ•Ž                โ•‘        +-+         โ•Ž
โ”‚        โ•Ž  โ•‘ โ”‚                  โ”‚  โ•Ž   o    โ•Ž    Container   โ•‘        +-+         โ•Ž
โ”‚        โ•Ž  โ•‘ โ•ฐโ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”โ•ฏ  โ•Ž   t    โ•Ž                โ•‘        |v|         โ•Ž
โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ–บ     Models     โ”‚   โ”‚   i    โ”‚                โ•‘        +-+         โ•Ž
โ”‚        โ•Ž  โ•‘ โ•ญโ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜โ•ฎ  โ•Ž   q    โ•Ž                โ•‘        +-+         โ•Ž
โ”‚        โ•Ž  โ•‘ โ”‚                  โ”‚  โ•Ž   u    โ•Ž                โ•‘        |e|         โ•Ž
โ”‚        โ•Ž  โ•‘ โ”‚    Agrest.io     โ”‚  โ•Ž   e    โ•Ž                โ•‘        +-+         โ•Ž
โ”‚        โ•Ž  โ•‘ โ”‚                  โ”‚  โ•Ž        โ•Ž                โ•‘        +-+         โ•Ž
โ”‚        โ•Ž  โ•‘ โ•ฐโ”€โ”€โ”€โ”€โ”€โ–ฒโ”€โ”€โ”€โ”€โ–ฒโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ•ถโ•ถโ•ถโ•ถโ•ถโ•ถโ•ถโ•ถโ”˜                โ•‘        |r|         โ•Ž
โ”‚        โ•Ž  โ•šโ•โ•โ•โ•โ•โ• โ”‚โ•โ•โ•โ•โ”‚โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•        +-+         โ•Ž
โ”‚        โ•Ž          HTTPSโ”‚                                                         โ•Ž
โ”‚        โ””โ•ถโ•ถโ•ถโ•ถโ•ถโ•ถโ•ถโ•ถโ•ถ โ”‚โ•ถโ•ถโ•ถโ•ถโ”‚โ•ถโ•ถโ•ถโ•ถโ•ถโ•ถโ•ถโ•ถโ•ถโ•ถโ•ถ โ•ถโ•ถโ•ถโ•ถโ•ถโ•ถโ•ถโ•ถโ•ถโ•ถโ•ถโ•ถโ•ถโ•ถโ•ถโ•ถโ•ถโ•ถโ•ถโ•ถโ•ถโ•ถโ•ถโ•ถโ•ถโ•ถโ•ถโ•ถโ•ถโ•ถโ•ถโ•ถโ•ถโ•ถโ•ถโ•ถโ•ถโ•ถโ•ถโ•ถโ•ถโ•ถโ•ถโ•ถโ•ถโ”˜
โ”‚                   โ”‚    โ”‚        PUT / UPDATE / DELETE
โ”‚Code               โ”‚    โ—„โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚generation         โ”‚    โ”‚        GET                               โ”‚
โ”‚                   โ—„โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”     โ”‚              C
โ”‚                   โ”‚    โ”‚                                    โ”‚     โ”‚
โ”‚        โ”Œโ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”               โ”Œโ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”   L
โ”‚        โ”‚   โ”‚                 โ”‚     โ”‚               โ”‚  โ”‚                  โ”‚   โ”‚
โ”‚        โ”‚   โ”‚ JAX-RS / Jersey โ”‚     โ”‚               โ”‚  โ”‚ Mantle/RestKit?  โ”‚   โ”‚   I
โ”‚        โ”‚   โ”‚                 โ”‚     โ”‚               โ”‚  โ”‚                  โ”‚   โ”‚
โ”‚        โ”‚   โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค     โ”‚               โ”‚  โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค   โ”‚   E
โ”‚        โ”‚   โ”‚                 โ”‚     โ”‚               โ”‚  โ”‚                  โ”‚   โ”‚
โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ–บ  Models         โ”‚  M  โ”‚          โ”Œโ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ–บ  Models          โ”‚ M โ”‚   N
โ”‚        โ”‚   โ”‚                 โ”‚     โ”‚          โ”‚    โ”‚  โ”‚                  โ”‚   โ”‚
โ”‚        โ”‚   โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜  V  โ”‚          โ”‚    โ”‚  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ V โ”‚   T
โ”‚        โ”‚                           โ”‚          โ”‚    โ”‚                         โ”‚
โ”‚        โ”‚   โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”  V  โ”‚          โ”‚    โ”‚  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”  V โ”‚
โ”‚        โ”‚   โ”‚                 โ”‚     โ”‚          โ”‚    โ”‚  โ”‚ GUI:   โ”‚        โ”‚    โ”‚   A
โ”‚        โ”‚   โ”‚GUI: SWT / JFace โ”‚  M  โ”‚          โ”‚    โ”‚  โ”‚  GTK   โ”‚  UIKit โ”‚  M โ”‚
โ”‚        โ”‚   โ”‚                 โ”‚     โ”‚          โ”‚    โ”‚  โ”‚        โ”‚        โ”‚    โ”‚   P
โ”‚        โ”‚   โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜     โ”‚          โ”‚    โ”‚  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜    โ”‚
โ”‚        โ”‚  SWT Java Desktop App     โ”‚          โ”‚    โ”‚   Mobile App (ObjFW)    โ”‚   P
โ”‚        โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜          โ”‚    โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
โ”‚                                               โ”‚                                  S
โ”‚                                               โ”‚
โ”‚                                               โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
   Code generation by ObjC plugin

=> Bootique.io - Framework for runnable Java apps | Agrest.io (Framework for REST data services) | Eclipse Jersey (JAX-RS implementation, client and server) | ObjFW: Lightweight, portable Objective-C framework

What needs to be done to achieve this?

  1. Finish the Objective-C bindings for GTK(4)

=> ObjGTKGen: Generates GObject/GTK bindings for ObjFW

  1. Wait for ObjFW to have KVO/OFCoding support

=> ObjFW: Ticket: OFCoding support (FR) | ObjFW: Ticket: KVO support (FR)

  1. Port Mantle or RestKit to ObjFW. Currently I don't know yet which ones suites better. I consider it important to bring up a good solution to cache data locally since you don't want to depend on the REST service (aka "the cloud").

=> GitHub: Mantle | GitHub: RestKit (this one was not mainted 3 years longer)

  1. Add a plugin to Apache Cayenne to generate fitting Objective-C models (for Mantle/RestKit)

Problems

Java IDEs like Eclipse are anything but light on resources and do not work on my old ThinkPad running on 8GB of RAM. Still Apache Cayenne provides abilities that would cost > 495โ‚ฌ if you take PHP, Doctrine ORM and Skipper18 under consideration.

It also seems SWT is maintained badly by the Eclipse community. I did not manage to make up an Eclipse configuration to build a SWT app after 4 hours of work.

Update from November 2024: Seems they updated their docs. Managed to get SWT up and running within some minutes. Just had to follow the docs.

=> https://www.eclipse.org/swt/eclipse.php

Sane app architecture the Java way was published on 2023-09-02.

The content on this site is licensed under CC BY-SA 4.0.

..........................................................................

=> ๐Ÿง‘โ€๐Ÿ’ป๐Ÿ John's Gemini capsule ๐Ÿฏ - Back to index

Proxy Information
Original URL
gemini://devbeejohn.de/posts/2023-09-02-Sane-app-architecture-the-Java-way.gmi
Status Code
Success (20)
Meta
text/gemini; lang=en
Capsule Response Time
224.753222 milliseconds
Gemini-to-HTML Time
9.564906 milliseconds

This content has been proxied by September (3851b).