$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 6 months? What about maintaining your enterprise application for longer than the 2-year lifecycle of these frameworks? This talk can provide you with insightful answers, share challenges and the solutions through the 5 pillars of a successful Java Web application extracted directly from the development of jBPM and Drools web workbenches.
Come and join me for this talk. I'll share how we're able to keep a 7-year old Java application, that combines modern techniques with a legacy codebase of more than 1 million LOC, up-to-date with an agile, sustainable and evolutionary web approach. Some key points you'll learn are:
* The advantages of Contract Based Development instead of a Framework Centric Development;
* How static typing is a central point in a huge web application;
* How we use the same programming model (Java EE) on the backend and browser ;
* How a Java to JS APIs allow your application to evolve over time and support heterogeneous (polyglot) web frameworks;
* The importance of a clean and unified UI framework for your enterprise architecture and how to do it on Java;

Eder Ignatowicz

July 11, 2017
Tweet

More Decks by Eder Ignatowicz

Other Decks in Programming

Transcript

  1. 5 pillars of a successful
    Java Web application
    Eder Ignatowicz
    Sr. Software Engineer @ Red Hat

    View Slide

  2. View Slide

  3. Which backend architecture?

    View Slide

  4. Java 9 modular, Reactive,
    Microservices, Vert.x
    Drools, Spring Boot,
    Zookeeper, Spark

    View Slide

  5. And on the front-end?

    View Slide

  6. View Slide

  7. View Slide

  8. View Slide

  9. View Slide

  10. Javascript Development
    is complex

    View Slide

  11. Web Javascript
    development is complex

    View Slide

  12. Web development
    will stay complex

    View Slide

  13. View Slide

  14. View Slide

  15. View Slide

  16. View Slide

  17. View Slide

  18. Which web stack?

    View Slide

  19. Which web architecture is most
    doable for this problem?

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  23. Large Scale Application
    Static
    Typing

    View Slide

  24. Large Scale Application
    Refactoring

    View Slide

  25. View Slide

  26. View Slide

  27. Large Scale Application
    JS Transpilers

    View Slide

  28. View Slide

  29. .java
    javac .class

    View Slide

  30. View Slide

  31. View Slide

  32. View Slide

  33. View Slide

  34. GWT
    <3

    View Slide

  35. GWT
    The Good Parts

    View Slide

  36. GWT GOOD PARTS
    Java to JavaScript

    View Slide

  37. GWT GOOD PARTS
    java.* emulation

    View Slide

  38. GWT GOOD PARTS
    DOM APIs

    View Slide

  39. GWT GOOD PARTS
    Java 8
    “client side"

    View Slide

  40. Java 8
    List myList =
    Arrays.asList("Java7", “Java8",
    "Java6", "Kotlin");
    myList
    .stream()
    .filter(s -> s.startsWith("J"))
    .map(String::toUpperCase)
    .sorted()
    .forEach(Console::log);
    Prints:
    JAVA6
    JAVA7
    JAVA8

    View Slide

  41. GWT GOOD PARTS
    Dev Tools

    View Slide

  42. View Slide

  43. GWT GOOD PARTS
    JS Interop

    View Slide

  44. 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

  45. 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

  46. Large Scale Application
    Refactoring

    View Slide

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

    View Slide

  48. Devs Full Stack
    “End-to-end” developers

    View Slide

  49. Devs Full Stack
    Shared Programming Model

    View Slide

  50. Devs Full Stack
    “Java EE” in browser

    View Slide

  51. View Slide

  52. ERRAI
    CDI on Browser

    View Slide

  53. @Dependent
    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;
    CDI NO BROWSER

    View Slide

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

    }

    View Slide

  55. public void onNewFile(@Observes ResourceAddedEvent event)
    {
    Window.alert(
    "ResourceAddedEvent:" +
    event.getPath().toURI() +
    " ['" + event.getMessage() + “‘]");
    }

    View Slide

  56. View Slide

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

    View Slide

  58. Devs Full Stack
    Shared Programming Model

    View Slide

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

    View Slide


  60. Pizza Types


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


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

    <% } %>


    Size



    Small

    Medium ( + 2$ )

    Large ( + 3$ )


    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

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


    {{ hero }}


    View Slide




  62. data-field="new-project">
    New Project


    View Slide

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

    View Slide

  64. View Slide





  65. Toggle navigation












    Home



    Design
    Processes & Tasks
    Runtime
    Settings







    Messages: 0





    Modified Datasources ExampleDS


    Error: System Failure



    Clear Messages






    Brian Johnson



    Preferences
    Logout








    Settings


    Welcome to BPM Suite


    Business Process Management (BPM) Suite offers a set of flexible, process management tools that support the way you need to work. Select a BPM tool below to get started.


    View Slide

  66. View Slide

  67. UX Integration
    Leave the HTML/CSS in peace

    View Slide

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

    View Slide

  69. View Slide

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

    View Slide

  71. Principles
    Not coupled to Frameworks
    Testable
    Not coupled with UI technology
    Not coupled with Database
    Independent of another systems

    View Slide

  72. View Slide

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

    View Slide

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

    View Slide

  75. View Slide

  76. Which web framework
    should I use?

    View Slide

  77. Which JS framework?

    View Slide

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

    View Slide

  79. What’s next for Angular 1.x?

    "In all honesty, no one really knows what will happen"
    https://toddmotto.com/future-of-angular-1-x

    View Slide

  80. 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

  81. "A good architecture allows
    volatile decisions to be easily
    changed”
    Robert C. Martin

    View Slide

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

    View Slide

  83. View Slide

  84. View Slide

  85. Programming Model
    Components:
    - Screen
    - Editors
    - Perspectives
    - Popups

    View Slide

  86. Programming Model
    LifeCycle:
    - OnStart
    - OnSave
    - IsDirty
    - OnClose
    - OnFocus
    - OnLostFocus
    - OnMayClose
    - OnReveal

    View Slide

  87. Perspective
    Editor
    Screen Screen

    View Slide

  88. Contract Based
    Screen -> Interface WorkbenchScreenActivity
    Editor -> Interface WorkbenchEditorActivity
    Perspective -> Interface PerspectiveActivity

    View Slide

  89. Perspectives
    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

  90. 7 years old code with
    “old school” GWT

    View Slide

  91. HTML 5 canvas
    fresh code

    View Slide

  92. 5~10 years life-span
    The Web architecture should be
    treated with the same respect as
    you treat your backend.

    View Slide

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

    View Slide

  94. @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

  95. View Slide

  96. 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

  97. Perspectives
    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
    Angular
    Perspective
    Adapter
    Angular native
    Perspective
    Any JS
    Perspective
    Adapter
    Any JS
    Framework

    View Slide

  98. Angular JS Screen

    View Slide

  99. Creating Components
    in Runtime

    View Slide

  100. View Slide

  101. View Slide

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

    View Slide

  103. Web development
    is complex

    View Slide

  104. Web applications are
    important pieces of
    our architecture

    View Slide

  105. Principles
    Not coupled to Frameworks
    Testable
    Not coupled with UI technology
    Not coupled with Database
    Independent of another systems

    View Slide

  106. Software architecture
    is trade-offs exercise

    View Slide

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

    View Slide

  108. Eder Ignatowicz
    @ederign
    http://bit.ly/5-pillars-web

    View Slide