B4J Question [SOLVED] B4J 6.30 BETA and ALPN

alwaysbusy

Expert
Licensed User
Longtime User
Is it possible 'the old way' is broken with jServer 3.00?

Java version:
B4X:
java version "1.8.0_171"
Java(TM) SE Runtime Environment (build 1.8.0_171-b11)
Java HotSpot(TM) Client VM (build 25.171-b11, mixed mode, sharing)

Using:
B4X:
#VirtualMachineArgs: -Xbootclasspath/p:alpn-boot-8.1.12.v20180117.jar

The log:
B4X:
Error occurred on line: 271 (ABMApplication)
java.lang.IllegalStateException: No Server ALPNProcessors!
   at org.eclipse.jetty.alpn.server.ALPNServerConnectionFactory.<init>(ALPNServerConnectionFactory.java:53)
   at anywheresoftware.b4j.object.ServerWrapper.Start(ServerWrapper.java:142)
   at abmaterial.ab.com.abmapplication._startserverhttp2(abmapplication.java:226)
   at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
   at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
   at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
   at java.lang.reflect.Method.invoke(Method.java:498)
   at anywheresoftware.b4a.shell.Shell.runMethod(Shell.java:625)
   at anywheresoftware.b4a.shell.Shell.raiseEventImpl(Shell.java:234)
   at anywheresoftware.b4a.shell.Shell.raiseEvent(Shell.java:168)
   at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
   at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
   at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
   at java.lang.reflect.Method.invoke(Method.java:498)
   at anywheresoftware.b4a.BA.raiseEvent2(BA.java:90)
   at anywheresoftware.b4a.ShellBA.raiseEvent2(ShellBA.java:94)
   at anywheresoftware.b4a.BA.raiseEvent(BA.java:77)
   at abmaterial.ab.com.main.main(main.java:29)
   Suppressed: java.util.ServiceConfigurationError: org.eclipse.jetty.io.ssl.ALPNProcessor$Server: Provider org.eclipse.jetty.alpn.conscrypt.server.ConscryptServerALPNProcessor could not be instantiated
       at java.util.ServiceLoader.fail(ServiceLoader.java:232)
       at java.util.ServiceLoader.access$100(ServiceLoader.java:185)
       at java.util.ServiceLoader$LazyIterator.nextService(ServiceLoader.java:384)
       at java.util.ServiceLoader$LazyIterator.next(ServiceLoader.java:404)
       at java.util.ServiceLoader$1.next(ServiceLoader.java:480)
       at org.eclipse.jetty.alpn.server.ALPNServerConnectionFactory.<init>(ALPNServerConnectionFactory.java:60)
       ... 17 more
   Caused by: java.lang.NoClassDefFoundError: org/conscrypt/OpenSSLProvider
       at java.lang.Class.getDeclaredConstructors0(Native Method)
       at java.lang.Class.privateGetDeclaredConstructors(Class.java:2671)
       at java.lang.Class.getConstructor0(Class.java:3075)
       at java.lang.Class.newInstance(Class.java:412)
       at java.util.ServiceLoader$LazyIterator.nextService(ServiceLoader.java:380)
       ... 20 more
   Caused by: java.lang.ClassNotFoundException: org.conscrypt.OpenSSLProvider
       at java.net.URLClassLoader.findClass(URLClassLoader.java:381)
       at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
       at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:349)
       at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
       ... 25 more
   Suppressed: java.lang.UnsupportedClassVersionError: org/eclipse/jetty/alpn/java/server/JDK9ServerALPNProcessor has been compiled by a more recent version of the Java Runtime (class file version 53.0), this version of the Java Runtime only recognizes class file versions up to 52.0
       at java.lang.ClassLoader.defineClass1(Native Method)
       at java.lang.ClassLoader.defineClass(ClassLoader.java:763)
       at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:142)
       at java.net.URLClassLoader.defineClass(URLClassLoader.java:467)
       at java.net.URLClassLoader.access$100(URLClassLoader.java:73)
       at java.net.URLClassLoader$1.run(URLClassLoader.java:368)
       at java.net.URLClassLoader$1.run(URLClassLoader.java:362)
       at java.security.AccessController.doPrivileged(Native Method)
       at java.net.URLClassLoader.findClass(URLClassLoader.java:361)
       at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
       at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:349)
       at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
       at java.lang.Class.forName0(Native Method)
       at java.lang.Class.forName(Class.java:348)
       at java.util.ServiceLoader$LazyIterator.nextService(ServiceLoader.java:370)
       at java.util.ServiceLoader$LazyIterator.next(ServiceLoader.java:404)
       at java.util.ServiceLoader$1.next(ServiceLoader.java:480)
       at org.eclipse.jetty.alpn.server.ALPNServerConnectionFactory.<init>(ALPNServerConnectionFactory.java:60)
       ... 17 more
 

OliverA

Expert
Licensed User
Longtime User
Suppressed: java.lang.UnsupportedClassVersionError: org/eclipse/jetty/alpn/java/server/JDK9ServerALPNProcessor has been compiled by a more recent version of the Java Runtime (class file version 53.0), this version of the Java Runtime only recognizes class file versions up to 52.0
Looks like that version is referencing JDK9, which may be an issue
https://github.com/jetty-project/jetty-alpn/issues/15
Suppressed: java.util.ServiceConfigurationError: org.eclipse.jetty.io.ssl.ALPNProcessor$Server: Provider org.eclipse.jetty.alpn.conscrypt.server.ConscryptServerALPNProcessor could not be instantiated
Looks like the conscrypt ALPN processor is already included in this version of Jetty (see the announcement for the B4J 6.30 Beta). If I read the docs correctly here (https://www.eclipse.org/jetty/documentation/9.4.x/jetty-ssl-distribution.html), all you need is to enable SSL (with proper keystore) and you should be good to go (no need for alpn-boot).
 
Upvote 0

OliverA

Expert
Licensed User
Longtime User
The correct way is to use Java 9 or (better) switch to Conscrypt

I posted the below previously here: https://www.b4x.com/android/forum/t...-longer-a-supported-option.92001/#post-581362
Note that you may wish to consider using the conscrypt SSL provider with jetty. Not only is it much faster than native SSL, but it supports ALPN in both java8 and java9 without the need to modify the boot path.

https://www.eclipse.org/jetty/documentation/9.4.x/jetty-ssl-distribution.html
So if one bites the bullet now and uses conscrypt SSL with JDK8, then one is ready to go with the next LTS version of the JDK/JRE.
 
Upvote 0

alwaysbusy

Expert
Licensed User
Longtime User
So Java 10 is considered stable enough for production?

Everything seems to work ok with JDK 8 & Conscrypt, except some oddities (I doubt if using java 10 will solve this):

1. The caching doesn't seem to work anymore (I asked our specials @mindful if he could look into this)
2. When the server is started in http2 mode, one can no longer use the 'non-secure' port. We go back in the loop situation:

In Websocket_connected() we had build in the following:
B4X:
Dim session As HttpSession
...
If session.IsNew Then
       session.Invalidate
       ABMShared.NavigateToPage(ws, "", "./")
       Return
End If

But now, session.IsNew always returns true if connecting via the non-secure way on a HTTP2 enabled server. So I guess from now on, we will always need to have a https filter that redirects the http requests to https.
 
Upvote 0

OliverA

Expert
Licensed User
Longtime User
The old method to configure Http/2 no longer works.

Suppressed: java.lang.UnsupportedClassVersionError: org/eclipse/jetty/alpn/java/server/JDK9ServerALPNProcessor has been compiled by a more recent version of the Java Runtime (class file version 53.0), this version of the Java Runtime only recognizes class file versions up to 52.0
at java.lang.ClassLoader.defineClass1(Native Method)

Dumb question: How is Jetty included in B4J? Do you compile it from source? It looks like it may have been compiled with JDK9+ (a guess from the error message). If one were to recompile it with JDK8 (again, a guess), the old way may work once more. Of course that would only be a short reprieve, since the next LTS version should be coming out soon.
 
Upvote 0

OliverA

Expert
Licensed User
Longtime User
When the server is started in http2 mode, one can no longer use the 'non-secure' port. We go back in the loop situation:
I just read somewhere that caching is an issue with HTTP/2. It is up to the client to make the request properly in order to not resent cached material. I'll try to find the link (it may not even be relevant).
 
Upvote 0

OliverA

Expert
Licensed User
Longtime User
Upvote 0

alwaysbusy

Expert
Licensed User
Longtime User
Just upgraded the feedback app, and all seems ok. It looks like HTTP2 does not cache IF you have a self-signed certificate (which I had at my workplace). Feedback has a real LetsEncrypt certificate and then everything is cached just fine.

upload_2018-5-15_17-36-32.png
 
Last edited:
Upvote 0

codie01

Active Member
Licensed User
Longtime User
HI Alian,

I have the same issue and need to move to ssl, I have a lets encrypt keystore.jks copied into the jar directory!

I have two Questions:

What version of the JDK is required?
What changes are required in my app to change to lets encrypt?

The following is my code in the MAIN module:

B4X:
 'Non-UI application (console / server application)
#Region  Project Attributes 
    #CommandLineArgs:
    #MergeLibraries: True 
    #AdditionalJar: mysql-connector-java-5.1.36-bin
    #AdditionalJar: mariadb-java-client-2.4.4.jar 
    #AdditionalJar: javase-2.2
    '#AdditionalJar: itextpdf-5.5.6    
    #AdditionalJar: itextpdf-5.0.6
    #AdditionalJar:nextreports-engine-9.1
    #AdditionalJar:commons-jexl-2.1.1
    #AdditionalJar:commons-logging-1.1.3
    #AdditionalJar:itext-2.1.7
    #AdditionalJar:itext-rtf-2.1.7
    #AdditionalJar:xstream-1.3.1
    #AdditionalJar:xstream-1.4.7
    #AdditionalJar:poi-3.7
#End Region

Sub Process_Globals
    Public srvr As Server    
    Dim ABM As ABMaterial
End Sub

Sub AppStart (Args() As String)
    ' the user needs to login
    'ABMShared.NeedsAuthorization = True
    
    ' Build the Theme ------------------------------------
    ABMShared.BuildTheme("mytheme")
    
    ' create the app
    Dim myApp As ABMApplication
    myApp.Initialize
        
    ' create the pages
    Dim myDashboard As dashboard2Genero
    myDashboard.Initialize
    Dim mySales As salesGenero
    mySales.Initialize
    Dim myContracts As contractsGenero
    myContracts.Initialize
    Dim myItems As itemsGenero
    myItems.Initialize
    Dim myCategory As categoryGenero
    myCategory.Initialize
    Dim myFees As feesGenero
    myFees.Initialize
    Dim myStores As storesGenero
    myStores.Initialize
    Dim myTake As takinGenero
    myTake.Initialize
    Dim myTakeout As takeoutGenero
    myTakeout.Initialize
    Dim myReports As reportGenero
    myReports.Initialize
    Dim myUsers As usersGenero
    myUsers.Initialize
    Dim myControl As controlGenero
    myControl.Initialize
    Dim mySchedule As scheduleGenero
    mySchedule.Initialize
    Dim myFirst As firstGenero
    myFirst.Initialize
    Dim myMail As mailGenero
    myMail.Initialize
    Dim myFile As filemanagerGenero
    myFile.Initialize
    
    ' add the pages to the app
    myApp.AddPage(myDashboard.Page)
    myApp.AddPage(mySales.Page)
    myApp.AddPage(myContracts.Page)
    myApp.AddPage(myItems.Page)
    myApp.AddPage(myCategory.Page)
    myApp.AddPage(myFees.Page)
    myApp.AddPage(myStores.Page)
    myApp.AddPage(myTake.Page)
    myApp.AddPage(myTakeout.Page)
    myApp.AddPage(myReports.Page)
    myApp.AddPage(myUsers.Page)
    myApp.AddPage(myControl.Page)
    myApp.AddPage(mySchedule.Page)
    myApp.AddPage(myFirst.Page)
    myApp.AddPage(myMail.Page)
    myApp.AddPage(myFile.Page)
    
    '/startbackground workers ------------------------------------
    srvr.AddBackgroundWorker("dashboardGenero")
    
    If ABMShared.mySocket = "1" Then
        Log("STARTED SERVER : HTTP/1")
        myApp.StartServer(srvr, "srvr", XXXXX)
        Else
        Log("STARTED SERVER : HTTP/2 - https")
        myApp.StartServerHTTP2(srvr, "srvr", XXXXX, YYYYY, "keystore", "###########", "###########")
    End If
    StartMessageLoop
End Sub

Many Thanks
 
Upvote 0
Top