React-InstrinsicReactJSX v1.0: example for kontraktor react/jsx SPA without nodejs (java implementation of jsx, npm and bundling)

React JSX front end app powered by a java backend, no node/npm/webpack required

Frontend

  • intrinsic react jsx transpilation
  • Ultra fast hot reloading / live editing (Disclaimer: breakpoints cannot be set inside Chrome then: use 'debugger;' instead)
  • built-in npm replacement dependency management ('JNPM') fetches missing imports on demand
  • integrated bundler/transpiler. Integrates google-clojure compiler to compile down to ES5 in production mode
  • Sophisticated java/javascript interoperation. Fulfil Promises from js by java code, server push by calling callbacks from java transparently to js client code.

Has been tested with major react-UI libs: react-material-ui, react-bootstrap and react-semantic-ui (should work with any npm powered js lib)

Server Side

  • Actor based async server (Java 8, node style threading model, but enables multithreading by assigning client sessions to additional threads)
  • (optional) Session handling, timeout, ressurrection (SPA client was away/offline and connects back)
  • Dynamically change connection type (http adaptive long poll or websockets) without code change

Very fast Live Editing / Live Reloading (updates within milliseconds after hitting 'Ctrl-S'):

Watch the video

Jnpm in action, session resurrection:

Watch the video

Getting started

Starter templates and scaffolding

Docs

Kontraktor's JSX transpilation + npm emulation

Talking from JavaScript with the Java Server

Examples for semantic-ui-react and react-bootstrap

Kontraktor home

Run this sample app

IDE

  • add project to your ide (from pom)
  • run ReactMaterialUITestApp with workingdir [...]/examples/webapp-spa/react-ui-lib-examples/react-material-ui
  • goto localhost:8080 in your browser
  • first request triggers download of required npm packages so give it like 50 seconds (wathc console)
  • set DEVMODE to false to get a (dynamically) bundled build

commandline:

git clone https://github.com/RuedigerMoeller/InstrinsicReactJSX.git
cd InstrinsicReactJSX/
mvn clean package
java -jar target/bundle.jar

browser: localhost:8080 (watch console on first request isntalling dependencies ..)

Note:

  • on the initial request, all missing npm dependencies are installed by kontraktor-Jnpm, this migth take up to a minute, once (watch console) per install.
  • as source is kept in separate files during development mode, loading is somewhat slowish (~3 seconds). Set DEVMODE to false inside ReactMaterialUITestApp, restart server in order to see loading time of bundled and minified app. Even then: First request triggers bundling (cached then) as kontraktor-http favors dynamic optimization over 'pre-building' (since 4.18.5 : static build artifacts support).

Simple starter templates and scaffolding

Session resurrection

  • goto localhost:8080 login (just some dummy nick)
  • press greet button
  • restart server
  • press greet button again.

Inner workings of resurrection: once a remote call to an unknown actor is received, a lookup is done from sessionid => userid (+pwd), then a new session actor is created. After that the remotecall is routed. Client receives a notification so it might update stale data.

Of course a real world app might associate arbitrary session data with a session id. Session resurrection is important for SPA apps (especially on mobile) as one frequently loses connection or keeps an SPA open for days without "refreshing".

Comments

  • Source reformatting bugs
    Source reformatting bugs

    Dec 12, 2017

    image

    Reply
  • exporting null objects
    exporting null objects

    Feb 12, 2018

    export let App = null;

    results in "resolvement error"

    workaround: 'export let App = {}'

    Reply
  • Followed steps to run via the command line and got the following two types of issues. How do I get past these?
    Followed steps to run via the command line and got the following two types of issues. How do I get past these?

    Jun 2, 2018

    First I see this in the log when I try to go to the site:

    I 09:28:37:729;DispatcherThread 8;JNPM installing '[email protected]' in C:\Users\sadmc\atos\workspace\InstrinsicReactJSX.\src\main\web\node_modules. W 09:28:38:338;DispatcherThread 8;JNPM distribution is empty or error 429 W 09:28:38:429;DispatcherThread 8;JNPM distribution is empty or error 429 W 09:28:38:433;DispatcherThread 8;JNPM distribution is empty or error 429 W 09:28:38:455;DispatcherThread 8;JNPM distribution is empty or error 429 W 09:28:38:463;DispatcherThread 8;JNPM distribution is empty or error 429 W 09:28:38:463;DispatcherThread 8;JNPM distribution is empty or error 429 W 09:28:38:463;DispatcherThread 8;JNPM distribution is empty or error 429 W 09:28:38:470;DispatcherThread 8;JNPM distribution is empty or error 429 W 09:28:38:472;DispatcherThread 8;JNPM distribution is empty or error 429 W 09:28:38:489;DispatcherThread 8;JNPM distribution is empty or error 429 W 09:28:38:493;DispatcherThread 8;JNPM distribution is empty or error 429 W 09:28:38:513;DispatcherThread 8;JNPM distribution is empty or error 429 W 09:28:38:526;DispatcherThread 8;JNPM distribution is empty or error 429 W 09:28:38:526;DispatcherThread 8;JNPM distribution is empty or error 429 W 09:28:38:528;DispatcherThread 8;JNPM distribution is empty or error 429 W 09:28:38:533;DispatcherThread 8;JNPM distribution is empty or error 429 W 09:28:38:533;DispatcherThread 8;JNPM distribution is empty or error 429 W 09:28:38:549;DispatcherThread 8;JNPM distribution is empty or error 429 W 09:28:38:553;DispatcherThread 8;JNPM distribution is empty or error 429 W 09:28:38:558;DispatcherThread 8;JNPM distribution is empty or error 429 W 09:28:38:558;DispatcherThread 8;JNPM distribution is empty or error 429 W 09:28:38:560;DispatcherThread 8;JNPM distribution is empty or error 429 W 09:28:38:560;DispatcherThread 8;JNPM distribution is empty or error 429 W 09:28:38:560;DispatcherThread 8;JNPM distribution is empty or error 429 W 09:28:38:571;DispatcherThread 8;JNPM distribution is empty or error 429 W 09:28:38:584;DispatcherThread 8;JNPM distribution is empty or error 429 W 09:28:38:584;DispatcherThread 8;JNPM distribution is empty or error 429 W 09:28:38:589;DispatcherThread 8;JNPM distribution is empty or error 429 W 09:28:38:604;DispatcherThread 8;JNPM distribution is empty or error 429 W 09:28:38:612;DispatcherThread 8;JNPM distribution is empty or error 429 W 09:28:38:612;DispatcherThread 8;JNPM distribution is empty or error 429 W 09:28:38:614;DispatcherThread 8;JNPM distribution is empty or error 429 W 09:28:38:614;DispatcherThread 8;JNPM distribution is empty or error 429 W 09:28:38:647;DispatcherThread 8;JNPM distribution is empty or error 429 W 09:28:38:649;DispatcherThread 8;JNPM distribution is empty or error 429 W 09:28:38:657;DispatcherThread 8;JNPM distribution is empty or error 429 W 09:28:38:658;DispatcherThread 8;JNPM distribution is empty or error 429 W 09:28:38:662;DispatcherThread 8;JNPM distribution is empty or error 429 W 09:28:38:666;DispatcherThread 8;JNPM distribution is empty or error 429 W 09:28:38:670;DispatcherThread 8;JNPM distribution is empty or error 429 W 09:28:38:724;DispatcherThread 8;JNPM distribution is empty or error 429 W 09:28:38:741;DispatcherThread 8;JNPM distribution is empty or error 429 W 09:28:38:761;DispatcherThread 8;JNPM distribution is empty or error 429 W 09:28:38:761;DispatcherThread 8;JNPM distribution is empty or error 429 W 09:28:38:899;DispatcherThread 8;JNPM distribution is empty or error 429 W 09:28:38:977;DispatcherThread 8;JNPM distribution is empty or error 429

    After that I see a bunch of these:

    I 09:28:39:577;XNIO-1 task-2;JSXIntrinsicTranspiler kontraktor-client not found. installing .. 'kontraktor-client' W 09:28:39:610;DispatcherThread 8;JNPM distribution is empty or error 429 org.nustaq.kontraktor.AwaitException: 429 at org.nustaq.kontraktor.Promise.awaitHelper(Promise.java:453) at org.nustaq.kontraktor.Promise.await(Promise.java:393) at org.nustaq.kontraktor.webapp.transpiler.JSXIntrinsicTranspiler.resolveImportSpec(JSXIntrinsicTranspiler.java:419) at org.nustaq.kontraktor.webapp.transpiler.JSXIntrinsicTranspiler.processJSX(JSXIntrinsicTranspiler.java:260) at org.nustaq.kontraktor.webapp.transpiler.JSXIntrinsicTranspiler.transpile(JSXIntrinsicTranspiler.java:43) at org.nustaq.kontraktor.webapp.javascript.DynamicResourceManager.getResource(DynamicResourceManager.java:181) at io.undertow.server.handlers.resource.DefaultResourceSupplier.getResource(DefaultResourceSupplier.java:39) at io.undertow.server.handlers.resource.ResourceHandler$1.handleRequest(ResourceHandler.java:205) at io.undertow.server.Connectors.executeRootHandler(Connectors.java:332) at io.undertow.server.HttpServerExchange$1.run(HttpServerExchange.java:812) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) at java.lang.Thread.run(Thread.java:748) E 09:28:39:645;XNIO-1 task-2;JSXIntrinsicTranspiler jnpm install timed out. Check Proxy JVM settings, internet connectivity or just retry

    I have a good internet connection. Thanks

    Reply
  • Namespace pollution in module exit code
    Namespace pollution in module exit code

    Sep 19, 2018

    const s = {} clashes

                                                                                                                                                                                                           
    Reply
  • another parse error
    another parse error

    Jul 30, 2018

    blank hinter targetprogress fails parsing

        return <TargetDisplay
          targetProgress= {.37}
    
    Reply
  • parse error
    parse error

    Jul 3, 2018

    Date.prototype.getWeekNumber = function () {
      let d = new Date(Date.UTC(this.getFullYear(), this.getMonth(), this.getDate()));
    

    leads to "undefined function let"

    Date.prototype.getWeekNumber = function() {
    

    worked

    Date.prototype.getWeekNumber = () => {
    

    Did not bound this as expected.

    Reply
  • npe when wrong import name is given
    npe when wrong import name is given

    Jan 16, 2018

    import {XX} from ''

    image

    Reply
  • "jar's" in text is rendered as 'jarss' by transpiler

    Jan 4, 2018

    4.20.1

                                                                                                                                                                                                            bug 
    Reply
  • sun.misc.Cleaner NoClassDefFoundError using JDK9
    sun.misc.Cleaner NoClassDefFoundError using JDK9

    Dec 31, 2017

    localhost:8080 refuses connection

    $ java -jar target/bundle.jar WARNING: An illegal reflective access operation has occurred WARNING: Illegal reflective access by org.nustaq.serialization.FSTClazzInfo (file:/home/alarm/projects/InstrinsicReactJSX/target/bundle.jar) to field java.lang.String.value WARNING: Please consider reporting this to the maintainers of org.nustaq.serialization.FSTClazzInfo WARNING: Use --illegal-access=warn to enable warnings of further illegal reflective access operations WARNING: All illegal access operations will be denied in a future release Exception in thread "main" java.lang.NoClassDefFoundError: sun/misc/Cleaner at org.nustaq.offheap.bytez.malloc.MMFBytez.init(MMFBytez.java:59) at org.nustaq.offheap.bytez.malloc.MMFBytez.(MMFBytez.java:38) at org.nustaq.offheap.FSTBinaryOffheapMap.resetMem(FSTBinaryOffheapMap.java:143) at org.nustaq.offheap.FSTBinaryOffheapMap.initFromFile(FSTBinaryOffheapMap.java:99) at org.nustaq.offheap.FSTBinaryOffheapMap.(FSTBinaryOffheapMap.java:76) at org.nustaq.offheap.FSTCodedOffheapMap.(FSTCodedOffheapMap.java:41) at org.nustaq.offheap.FSTSerializedOffheapMap.(FSTSerializedOffheapMap.java:46) at org.nustaq.offheap.FSTAsciiStringOffheapMap.(FSTAsciiStringOffheapMap.java:66) at org.nustaq.offheap.FSTAsciiStringOffheapMap.(FSTAsciiStringOffheapMap.java:81) at sample.reactmaterial.PersistanceDummy.(PersistanceDummy.java:18) at sample.reactmaterial.ReactMaterialUITestApp.(ReactMaterialUITestApp.java:27) at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62) at java.base/jdk.internal.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45) at java.base/java.lang.reflect.Constructor.newInstance(Constructor.java:488) at java.base/java.lang.Class.newInstance(Class.java:558) at org.nustaq.kontraktor.impl.ActorsImpl.makeProxy(ActorsImpl.java:69) at org.nustaq.kontraktor.impl.ActorsImpl.newProxy(ActorsImpl.java:124) at org.nustaq.kontraktor.impl.ActorsImpl.newProxy(ActorsImpl.java:110) at org.nustaq.kontraktor.Actors.AsActor(Actors.java:187) at sample.reactmaterial.ReactMaterialUITestApp.main(ReactMaterialUITestApp.java:88) Caused by: java.lang.ClassNotFoundException: sun.misc.Cleaner at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:582) at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:185) at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:496) ... 21 more

    JDK9 
    Reply