Upgrade to Pro — share decks privately, control downloads, hide ads and more …

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 full-size slide

  2. Which backend architecture?

    View full-size slide

  3. And what about front-end?

    View full-size slide

  4. Javascript Development
    is complex

    View full-size slide

  5. Web Javascript
    development is complex

    View full-size slide

  6. Web development
    will stay complex

    View full-size slide

  7. Which web stack?

    View full-size slide

  8. Which web architecture
    best fits for this problem?

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

  12. Static Typing
    Large Scale Application

    View full-size slide

  13. Refactoring
    Large Scale Application

    View full-size slide

  14. Large Scale Application

    View full-size slide

  15. JavaScript Transpilers
    Large Scale Application

    View full-size slide

  16. Large Scale Application

    View full-size slide

  17. .java
    javac .class
    Large Scale Application

    View full-size slide

  18. The Good Parts

    View full-size slide

  19. GWT • Good Parts
    Java to JavaScript

    View full-size slide

  20. GWT • Good Parts
    java.* emulation

    View full-size slide

  21. GWT • Good Parts
    JS Interop

    View full-size slide

  22. 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 full-size slide

  23. 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 full-size slide

  24. Refactoring
    Large Scale Application

    View full-size slide

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

    View full-size slide

  26. Shared
    Programming Model
    Devs Full Stack

    View full-size slide

  27. “Java EE” in browser
    Devs Full Stack

    View full-size slide

  28. CDI-Lite
    Devs Full Stack

    View full-size slide

  29. Devs Full Stack

    View full-size slide

  30. CDI @ Browser
    ERRAI

    View full-size slide

  31. 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 full-size slide

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

    View full-size slide

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

    View full-size slide

  34. CDI no Browser

    View full-size slide

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

    View full-size slide

  36. Shared
    Programming Model
    Devs Full Stack

    View full-size slide

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

    View full-size slide


  38. 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 full-size slide

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


    {{ hero }}


    View full-size slide

  40. 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 full-size slide





  41. Toggle navigation












    Home



    Design
    Processes & Tasks
    Runtime
    Settings







    Messages: 0





    Modified Datasources ExampleDS


    Error: System Failure



    Clear Messages






    Brian Johnson



    ...

    View full-size slide

  42. Leave the HTML/CSS in peace
    UX Integration

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

  48. Which web framework
    should I use?

    View full-size slide

  49. Which JS framework?

    View full-size slide

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

    View full-size slide

  51. 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 full-size slide

  52. 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 full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

  57. Screen Screen
    Editor
    Perspective

    View full-size slide

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

    View full-size slide

  59. 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 full-size slide

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

    View full-size slide

  61. HTML 5 canvas
    fresh code

    View full-size slide

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

    View full-size slide

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

    View full-size slide

  64. @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 full-size slide

  65. 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 full-size slide

  66. 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 full-size slide

  67. Angular JS Screen

    View full-size slide

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

    View full-size slide

  69. Web development
    is complex

    View full-size slide

  70. Web applications are
    important pieces of
    our architecture

    View full-size slide

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

    View full-size slide

  72. Software architecture
    is trade-offs exercise

    View full-size slide

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

    View full-size slide

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

    View full-size slide