B4J Tutorial Non-UI Applications

Erel

Administrator
Staff member
Licensed User
B4J currently supports two types of applications: UI applications (based on JavaFX) and Non-UI applications.

Non-UI applications are standard Java applications. Usually the input to such applications is with command line arguments.

You should create a new project and select:



The program starts with:
B4X:
Sub AppStart(Args() As String)

End Sub
The program will end after this sub unless you call StartMessageLoop. Calling StartMessageLoop means that the main thread is now handling an internal message queue. This is useful if you need to wait for some other event to happen.

For example, we will create a very simple "curl" application. curl is a Linux app that allows you to send Http requests.

In this case the program will receive one argument which is the URL, it will download it and print the downloaded resource.

In order to test it we need to provide the command line argument. This is done with the #CommandLineArgs module attribute.

The complete code:
B4X:
'Non-UI application (console application)
#Region  Project Attributes
   #CommandLineArgs: http://www.basic4ppc.com
#End Region

Sub Process_Globals
  
End Sub

Sub AppStart (Args() As String)
   If Args.Length = 0 Then
     Log("URL is missing.")
     ExitApplication2(1)
   End If
   Dim j As HttpJob
   j.Initialize("j", Me)
   j.Download(Args(0))
   StartMessageLoop
End Sub

Sub JobDone(Job As HttpJob)
   If Job.Success Then
     Log(Job.GetString)
   Else
     Log(Job.ErrorMessage)
   End If
   Job.Release
   ExitApplication2(0) 'exit the application. Without this call the program will just hang.
End Sub
The jar file created is not an executable jar. You need to run it by calling the java program.
The syntax is:
B4X:
java -cp <jar file> <package>.main <args>
You can create a batch file or script to run it.



Note that instead of referencing jHttpUtils2, we are using its source code. jHttpUtils2 library depends on jFX (for the GetBitmap method which is removed here).
 

Attachments

Last edited:

Erel

Administrator
Staff member
Licensed User
You can use JavaObject to read the System input stream. You will need to run it in Release mode. The program will fail, however you will be able to start it from a cmd window:
B4X:
Sub Process_Globals
   Private reader As TextReader
End Sub

Sub AppStart (Args() As String)
   Dim sys As JavaObject
   sys.InitializeStatic("java.lang.System")
   reader.Initialize(sys.GetField("in"))
   Log("Enter name: ")
   Log("You have entered: " & ReadLine)
   Log("Enter family name: ")
   Dim f As String = ReadLine
   Log("Family: " & f)
End Sub

Sub ReadLine As String
   Return reader.ReadLine
End Sub
 

mrred128

Active Member
Licensed User
I guess for debugging purposes, you could set up a text file to read the input from. You would just have to comment out that code for the release.
 

Erel

Administrator
Staff member
Licensed User
You can use a Try / Catch block to decide whether you need to read the input from a file or from the console:
B4X:
Try
 reader.Initialize(sys.GetField("in"))
Catch
 Log("IDE Mode")
 reader.Initialize(File.OpenInput(...))
End Try
 

positrom2

Active Member
Licensed User
I tried the original program, getting the error:
C:\Program Files (x86)\Anywhere Software\B4J\samples\CMD\Objects>java -jar cmd.j
ar
Program started.
main.start (java line: 33)
java.lang.Exception: Sub appstart signature does not match expected signature.
at anywheresoftware.b4a.BA.raiseEvent2(BA.java:95)
at anywheresoftware.b4a.BA.raiseEvent(BA.java:84)
at b4j.cmd.main.start(main.java:33)
at com.sun.javafx.application.LauncherImpl$5.run(Unknown Source)
at com.sun.javafx.application.PlatformImpl$5.run(Unknown Source)
at com.sun.javafx.application.PlatformImpl$4$1.run(Unknown Source)
at com.sun.javafx.application.PlatformImpl$4$1.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at com.sun.javafx.application.PlatformImpl$4.run(Unknown Source)
at com.sun.glass.ui.InvokeLaterDispatcher$Future.run(Unknown Source)
at com.sun.glass.ui.win.WinApplication._runLoop(Native Method)
at com.sun.glass.ui.win.WinApplication.access$100(Unknown Source)
at com.sun.glass.ui.win.WinApplication$3$1.run(Unknown Source)
at java.lang.Thread.run(Unknown Source)
 

Erel

Administrator
Staff member
Licensed User
When you create a new project, you should choose non-UI app:
 

positrom2

Active Member
Licensed User
Thank you, I missed to change for that since the IDE comes in UI-mode when starting the application...
 

Erel

Administrator
Staff member
Licensed User
I've added this image to the tutorial. It was not clear enough.
 

koaunglay

Member
Licensed User
You can use JavaObject to read the System input stream. You will need to run it in Release mode. The program will fail, however you will be able to start it from a cmd window:
B4X:
Sub Process_Globals
   Private reader As TextReader
End Sub

Sub AppStart (Args() As String)
   Dim sys As JavaObject
   sys.InitializeStatic("java.lang.System")
   reader.Initialize(sys.GetField("in"))
   Log("Enter name: ")
   Log("You have entered: " & ReadLine)
   Log("Enter family name: ")
   Dim f As String = ReadLine
   Log("Family: " & f)
End Sub

Sub ReadLine As String
   Return reader.ReadLine
End Sub
Hi Erel! Can I use it in UI Application.
 

Erel

Administrator
Staff member
Licensed User
Yes, you can start UI applications from a batch file. Please start a new thread if you need more information.
 

mrred128

Active Member
Licensed User
It has to have X11 (gui) installed, and running inside it. Even if you only use console i/o, it get's linked with guicode and will not run without it. You need to know at project start time how you need your app run. It's a bit of a pain, after the fact.
 
Top