$30 off During Our Annual Pro Sale. View Details »

5 Pillars of a Successful Java Web Application

5 Pillars of a Successful Java Web Application

Swamped by new JavaScript frameworks that are born every six months? What about maintaining your enterprise application for longer than the two-year lifecycle of these frameworks? This session can provide you with insightful answers. It shares challenges and solutions through the five pillars of a successful Java web application, extracted directly from the development of jBPM and Drools web workbenches. The speaker how his team is able to keep a seven-year-old Java application that combines modern techniques with a legacy codebase of more than one million lines of code up to date with an agile, sustainable, and evolutionary web approach.

Eder Ignatowicz

October 01, 2017
Tweet

More Decks by Eder Ignatowicz

Other Decks in Technology

Transcript

  1. 5 Pillars of a Successful
    Java Web Application
    Eder Ignatowicz
    Sr. Software Engineer @ Red Hat
    Alex Porcelli
    Principal Software Engineer @ Red Hat

    View Slide

  2. View Slide

  3. Which backend architecture?

    View Slide

  4. And what about front-end?

    View Slide

  5. View Slide

  6. Javascript Development
    is complex

    View Slide

  7. Web Javascript
    development is complex

    View Slide

  8. Web development
    will stay complex

    View Slide

  9. View Slide

  10. View Slide

  11. View Slide

  12. Which web stack?

    View Slide

  13. Which web architecture
    best fits for this problem?

    View Slide

  14. 5 pillars:
    Large scale application
    Full stack Developers
    UX Integration
    5~10 years Life-Span
    Interoperability

    View Slide

  15. s
    5 pillars:
    Large scale application
    Full stack Developers
    UX Integration
    5~10 years Life-Span
    Interoperability

    View Slide

  16. 1mi+ lines of web code
    5 projects
    ~150 subprojects
    ~30 devs
    Code base of 7+ years
    Large Scale Application

    View Slide

  17. Static Typing
    Large Scale Application

    View Slide

  18. Refactoring
    Large Scale Application

    View Slide

  19. Large Scale Application

    View Slide

  20. JavaScript Transpilers
    Large Scale Application

    View Slide

  21. Large Scale Application

    View Slide

  22. .java
    javac .class
    Large Scale Application

    View Slide

  23. View Slide

  24. View Slide

  25. View Slide

  26. View Slide

  27. The Good Parts

    View Slide

  28. GWT • Good Parts
    Java to JavaScript

    View Slide

  29. GWT • Good Parts
    java.* emulation

    View Slide

  30. GWT • Good Parts
    JS Interop

    View Slide

  31. JS Interop • Consume
    Java
    @JsType(isNative = true)
    public abstract class JQuery {
    @JsMethod(namespace=GLOBAL)
    public native static JQuery $(String selector);
    public native JQuery css(String prop, String val);
    public native JQuery attr(String name, String val);
    }
    Java
    import static jquery.JQuery.$;
    // ...
    $("ul > li").css("color", "red").attr("data-level", "first");

    View Slide

  32. JS Interop • Expose
    Java
    package foo;
    @JsType
    public class Dora {
    public boolean late = true;
    public Dora() {}
    public String auAu() { return "Hello QCon!";}
    }
    JavaScript
    var dora = new foo.Dora();
    if (dora.late) {
    alert(dora.auAu());
    }

    View Slide

  33. Refactoring
    Large Scale Application

    View Slide

  34. 5 pillars:
    Large scale application
    Full stack Developers
    UX Integration
    5~10 years Life-Span
    Interoperability

    View Slide

  35. Shared
    Programming Model
    Devs Full Stack

    View Slide

  36. “Java EE” in browser
    Devs Full Stack

    View Slide

  37. CDI-Lite
    Devs Full Stack

    View Slide

  38. Devs Full Stack

    View Slide

  39. CDI @ Browser
    ERRAI

    View Slide

  40. CDI no Browser
    @ApplicationScoped
    public class ProjectsView {
    @Inject
    Document document;
    @Inject
    @DataField( "projects-view" )
    Div view;
    @Inject
    @DataField( "new-project" )
    Button newProject;
    @Inject
    @DataField( "projects-list" )
    UnorderedList projectsList;
    @Inject
    Instance projects;

    View Slide

  41. CDI no Browser
    if (!filter.doFilter(event)) {
    ...
    if (event.kind().equals(StandardWatchEventKind.ENTRY_ADD)) {
    resourceAddedEvent.fire(buildEvent(ResourceAddedEvent.class,
    event).getK2());
    }
    ...
    }

    View Slide

  42. CDI no Browser
    public void onNewFile(@Observes ResourceAddedEvent event) {
    Window.alert("ResourceAddedEvent:" +
    event.getPath().toURI() +
    " ['" + event.getMessage() + "']");
    }

    View Slide

  43. CDI no Browser

    View Slide

  44. ERRAI BUS
    Server
    Browser
    Browser Browser
    Browser
    Long Polling
    Web Sockets
    SSE

    View Slide

  45. Shared
    Programming Model
    Devs Full Stack

    View Slide

  46. 5 pillars:
    Large scale application
    Full stack Developers
    UX Integration
    5~10 years Life-Span
    Interoperability

    View Slide


  47. Pizza Types


    <% for ( Pizza pizza : pizzaTypes ) { %>


    <%=pizza.getName()%>
    <%=pizza.getPrice()%>$

    <% } %>


    Size
    Extra Toppings

    <% for ( int j = 0; j < 3; j++ ) { %>


    <% for ( int i = sliceSize * j; i < ( j + 1 ) * sliceSize; i++ ) { %>


    <%=pizzaToppings.get( i )%>

    <% }
    if ( j == 0 && remainder > 0 ) {
    %>


    <%=pizzaToppings.get( pizzaToppings.size() - 2 )

    <% } else if ( j == 1 && remainder > 1 ) { %>


    <%=pizzaToppings.get( pizzaToppings.size() - 1 )%>

    <% } %>


    <% } %>

    Each extra topping is 0.65$


    View Slide

  48. {{title}}
    My favorite hero is: {{myHero}}
    Heroes:


    {{ hero }}


    View Slide





  49. New Project


    View Slide

  50. ERRAI UI
    @Dependent
    @Templated
    public class ProjectsView {
    @Inject
    @DataField( "projects-view" )
    Div view;
    @Inject
    @DataField( "new-project" )
    Button newProject;
    @Inject
    @DataField( "projects-list" )
    UnorderedList projectsList;
    }

    View Slide

  51. View Slide





  52. Toggle navigation












    Home



    Design
    Processes & Tasks
    Runtime
    Settings







    Messages: 0





    Modified Datasources ExampleDS


    Error: System Failure



    Clear Messages






    Brian Johnson



    ...

    View Slide

  53. View Slide

  54. Leave the HTML/CSS in peace
    UX Integration

    View Slide

  55. 5 pillars:
    Large scale application
    Full stack Developers
    UX Integration
    5~10 years Life-Span
    Interoperability

    View Slide

  56. View Slide

  57. Hexagonal Architecture - Alistair Cockburn
    Onion Architecture - Jeffrey Palermo
    DCI - James Coplien e Trygve Reenskaug.
    BCE - Ivar Jacobson
    Clean Architecture - Robert C. Martin
    Architecture

    View Slide

  58. Decoupled from Frameworks
    Testable
    Decoupled from UI
    Decoupled from Database
    Independent of external systems
    Principles

    View Slide

  59. View Slide

  60. “Architecture is about intent.
    We have made it about
    frameworks and details”
    Robert C. Martin

    View Slide

  61. APPFORMER VFS
    Use Cases
    VFS
    API
    Regular FS
    Clustering
    GIT FS

    View Slide

  62. View Slide

  63. Which web framework
    should I use?

    View Slide

  64. Which JS framework?

    View Slide

  65. JS framework
    choice
    Years
    1 2 3 4 5 6
    First
    Release
    Danger
    0

    View Slide

  66. https://toddmotto.com/future-of-angular-1-x
    What’s next for Angular 1.x?
    “In all honesty, no one really knows what will happen”

    View Slide

  67. 1 2 3 4 5 6
    Years
    Deliver
    JS
    Framework
    Choice
    Learning
    Curve
    Project Canceled
    or new version
    is incompatible
    Rewrite on the new
    JS framework
    Learning
    Curve
    Project Canceled
    or new version
    is incompatible
    Rewrite on the new
    JS framework
    Learning
    Curve

    View Slide

  68. “A good architecture allows
    volatile decisions to be
    easily changed”
    Robert C. Martin

    View Slide

  69. What if I dealt with the volatility of
    JS frameworks as a fact?

    View Slide

  70. View Slide

  71. View Slide

  72. Component Model:
    • Screen
    • Editors
    • Perspectives
    • Popups
    Programming Model

    View Slide

  73. LifeCycle:
    • OnStart
    • OnSave
    • IsDirty
    • OnClose
    Programming Model
    ...

    View Slide

  74. Screen Screen
    Editor
    Perspective

    View Slide

  75. Programming Model
    Screen
    Editor
    Perspective
    → Interface WorkbenchScreenActivity
    → Interface WorkbenchEditorActivity
    → Interface PerspectiveActivity

    View Slide

  76. Perspectives Lookup
    AppFormer
    Lookup
    Perspective
    ERRAI
    CDI BEAN
    MANAGER
    Scan all
    Perspective Activity
    Implementations
    GWT Perspective
    Adapter
    OLD GWT WIDGET
    ERRAI UI Perspective
    Adapter
    Plain HTML Errai UI

    View Slide

  77. 7+ years old code with
    “old school” GWT

    View Slide

  78. HTML 5 canvas
    fresh code

    View Slide

  79. 5~10 years Life-Span
    The Web architecture should be
    treated with the same respect as
    you treat your backend.

    View Slide

  80. 5 pillars:
    Large scale application
    Full stack Developers
    UX Integration
    5~10 years Life-Span
    Interoperability

    View Slide

  81. @WorkbenchPerspective(identifier = “HomePerspective", isDefault = true)
    @Templated
    public class HomePerspective implements IsElement {
    @Inject
    @DataField
    @WorkbenchPanel(parts = "MoodScreen?uber=fire&uber1=fire1")
    Div moodScreen;
    @Inject
    @DataField
    @WorkbenchPanel(parts = "HomeScreen?uber=fire")
    Div homeScreen;
    @Inject
    @DataField
    @WorkbenchPanel(parts = "AnotherScreen")
    Div anotherScreen;
    }
    @JsType
    public interface PerspectiveActivity{
    PerspectiveDefinition getDefaultPerspectiveLayout();
    @Override
    default String getName() {
    return getDefaultPerspectiveLayout().getName();
    }
    boolean isDefault();
    Menus getMenus();
    ToolBar getToolBar();
    }

    View Slide

  82. View Slide

  83. function TodoCtrl($scope) {
    $scope.placeText = "MiscellaneousFeatures";
    $scope.todos = [
    {text: 'learn angular', done: true},
    {text: 'build an angular app', done: false}
    ];
    $scope.addTodo = function () {
    $scope.todos.push({text: $scope.todoText, done: false});
    $scope.todoText = '';
    };
    $scope.remaining = function () {
    var count = 0;
    angular.forEach($scope.todos, function (todo) {
    count += todo.done ? 0 : 1;
    });
    return count;
    };
    $scope.archive = function () {
    var oldTodos = $scope.todos;
    $scope.todos = [];
    angular.forEach(oldTodos, function (todo) {
    if (!todo.done) {
    $scope.todos.push(todo);
    }
    });
    };
    $scope["goto"] = function () {
    $goToPlace($scope.placeText);
    };
    }



    {{remaining()}} of {{todos.length}} remaining [
    archive ]

    Todos


    {{todo.text}}
























    $registerPlugin({
    id: "my_angular_js",
    type: "angularjs",
    templateUrl: "angular.sample.html",
    title: function () {
    return "angular " + Math.floor(Math.random() * 10);
    },
    on_close: function () {
    alert("this is a pure JS alert!");
    }
    });

    View Slide

  84. Perspectives
    GWT Perspective
    Adapter
    OLD GWT WIDGET
    ERRAI UI
    Perspective
    Adapter
    Plain HTML Errai UI
    Angular
    Perspective
    Adapter
    Angular native
    Perspective
    Any JS Perspective
    Adapter
    Any JS Framework
    AppFormer
    Lookup
    Perspective
    ERRAI
    CDI BEAN
    MANAGER
    Scan all
    Perspective Activity
    Implementations

    View Slide

  85. Angular JS Screen

    View Slide

  86. 5 pillars:
    Large scale application
    Full stack Developers
    UX Integration
    5~10 years Life-Span
    Interoperability

    View Slide

  87. Web development
    is complex

    View Slide

  88. Web applications are
    important pieces of
    our architecture

    View Slide

  89. Decoupled from Frameworks
    Testable
    Decoupled from UI
    Decoupled from Database
    Independent of external systems
    Principles

    View Slide

  90. Software architecture
    is trade-offs exercise

    View Slide

  91. 5 pillars:
    Large scale application
    Full stack Developers
    UX Integration
    5~10 years life-span
    Interoperability

    View Slide

  92. Thank you.
    Eder Ignatowicz
    Sr. Software Engineer @ Red Hat
    Alex Porcelli
    Principal Software Engineer @ Red Hat

    View Slide

  93. View Slide