B4J Question [SOLVED] Error using #If Java in non-ui B4J app - help desperately sought

JackKirk

Well-Known Member
Licensed User
Longtime User
I am tearing what little hair I have left out on this.

Copilot and Grok run round in circles.

I am attempting to filter logs in a non-ui B4J app (an ABMaterial framework web app):

B4X:
Public Sub RedirectFilteredLogs
    Dim system As JavaObject
    system.InitializeStatic("java.lang.System")

    ' Capture original System.out
    Dim originalOut As JavaObject = system.GetField("out")

    ' Initialize the custom PrintStreamWrapper
    Dim filteredStream As JavaObject
    filteredStream.InitializeNewInstance("PrintStreamWrapper", Array(originalOut, Me))
    system.RunMethod("setOut", Array(filteredStream)) ' Redirect standard output
    system.RunMethod("setErr", Array(filteredStream)) ' Redirect error output
End Sub

Public Sub ProcessLogMessage(message As String)
    If message.Contains("DEBUG") = False Then 'expand as necessary
        File.WriteString(File.DirApp, "filtered_logs.txt", message & Chr(10))
        CallSubDelayed2(Me, "ProcessLogMessageInternal", message)
    End If
End Sub

Public Sub ProcessLogMessageInternal(message As String)
    Dim system As JavaObject
    system.InitializeStatic("java.lang.System")
    Dim originalOut As JavaObject = system.GetField("out")
    originalOut.RunMethod("println", Array(message))
End Sub

#If Java
import java.io.PrintStream;
import java.lang.reflect.Method;

public class PrintStreamWrapper extends PrintStream {
    private Object b4jModule;

    public PrintStreamWrapper(PrintStream original, Object b4jModule) {
        super(original);
        this.b4jModule = b4jModule;
    }

    @Override
    public void println(String message) {
        try {
            if (b4jModule != null) {
                Method method = b4jModule.getClass().getMethod("ProcessLogMessage", String.class);
                method.invoke(b4jModule, message);
            } else {
                System.out.println("Error: b4jModule is null.");
            }
        } catch (Exception e) {
            System.out.println("Exception calling ProcessLogMessage: " + e.getMessage());
        }
    }
}
#End If

In DEBUG mode it compiles OK but fails with run time error:
where line 1295 is:
filteredStream.InitializeNewInstance("PrintStreamWrapper", Array(originalOut, Me))

I know I'm doing something stupidly wrong but what?

Any help gratefully accepted...


EDIT: see final solution here:
https://www.b4x.com/android/forum/t...-with-assistance-of-microsoft-copilot.167188/
 
Last edited:

JackKirk

Well-Known Member
Licensed User
Longtime User
Digging a bit, i find that in ...\Objects\bin\classes\com\ab\template there is a file main$PrintStreamWrapper.class all freshly minted.

com.ab.template is the projects package name.
 
Upvote 0

hatzisn

Expert
Licensed User
Longtime User
Search in Google the full name of the class f.e. "xxxx.yyyyy.zzzzzzz.wwwwww.PrintStreamWrapper"
 
Upvote 0

JackKirk

Well-Known Member
Licensed User
Longtime User
.PrintStreamWrapper is my own
 
Upvote 0

hatzisn

Expert
Licensed User
Longtime User
Sorry, a mistake. Use your package name+module name in non capital letters+class name.
 
Upvote 0

hatzisn

Expert
Licensed User
Longtime User
And maybe module name is not needed.
 
Last edited:
Upvote 0

JackKirk

Well-Known Member
Licensed User
Longtime User
Thanks Erel, I now have a fully functioning Log message filter for B4J (well at least non-UI but should work on UI), see:
https://www.b4x.com/android/forum/t...-with-assistance-of-microsoft-copilot.167188/
 
Upvote 0