3 Integrating WebLogic Server JMS with Helidon

Integrating the Oracle WebLogic Server (WebLogic Server) Java Message Service (JMS) with Helidon enables the Helidon applications to send and receive messages to and from WebLogic Server asynchronously. The WebLogic Server applications and Helidon microservices communicate through messaging, in one or both directions.
The following graphic illustrates the transmission of messages between WebLogic Server JMS and Helidon:

Figure 3-1 WebLogic Server JMS Integration with Helidon



This chapter includes the following topics:

Prerequisites

To integrate WebLogic Server with Helidon for JMS, it is assumed that you have already deployed WebLogic Server and Helidon in a Kubernetes cluster. See Preparing the Kubernetes Cluster for WebLogic Server and Helidon Integration.
In addition, ensure that you complete the following tasks:
  • Configure/create the WebLogic Server JMS resources, before adding them as part of the Helidon JMS connector configurations.
  • To send/receive JMS messages from Helidon to WebLogic Server JMS destinations, specify the WebLogic Server T3/T3S connection details. Enable the T3/T3S channels for communication in WebLogic Server and ensure that you are able to connect to T3/T3S from the Helidon application.
  • Add the thin client JAR files to the local Maven repository and refer to it as part of the Maven dependencies.

Enabling the T3/T3S Channel in the WebLogic Kubernetes Operator

WebLogic Server supports several ways to configure the T3/T3S channel in the WebLogic Kubernetes Operator (Operator). You can create the T3/T3S channel using one of the following options:
  • WebLogic Server Administration Console: The Domain in Persistent Volume (PV) domain home pattern enables you to configure the channel using the WebLogic Server Administration Console. For more information about this pattern, see Domain Home on a PV.
  • WebLogic Scripting Tool (WLST): The Domain in Persistent Volume (PV) domain home pattern enables you to configure the channel using WLST. See Domain Home on a PV.
  • WebLogic Deploy Tooling (WDT) model: The Model in Image domain home pattern enables you to configure the channel using the WDT model files and application archives. See Model in Image.

For information about external WebLogic clients in WebLogic Kubernetes Operator, see External WebLogic Clients.

Creating the T3/T3S Channel Using the Administration Console

To create the T3/T3S channel for the Administration Server:

  1. Log in to the WebLogic Server Administration Console and click Lock & Edit to obtain the configuration lock.
  2. In the left pane of the console, expand Environment and select Servers.
  3. On the Servers page, select the WebLogic Server Administration Server (for example: admin-server) from the list of servers.
  4. Go to the Protocols tab, select the Channels tab, and then click New.
  5. In the network channel Name field, enter admin-t3-channel, select Protocol as t3, and then click Next.
  6. In the Listen Port field, enter 30014, for External Listen Address, enter <Master IP>, and for External Listen Port, enter 30014. Leave the Listen Address field blank.
  7. Click Finish to create the network channel for admin-server.

To create the T3 channel for the dynamic cluster:

  1. Log in to the WebLogic Server Administration Console and click Lock & Edit to obtain the configuration lock.
  2. In the left pane of the console, expand Environment and select Clusters, and then select Server Template.
  3. From the list of server templates, select the target server template (for example: server-template-1).
  4. Go to the Protocols tab, click the Channels tab, and then click New.
  5. In the network channel Name field, enter the name of the network channel (for example: cluster-t3-channel), select Protocol as t3 or t3s, and then click Next.
  6. In the Listen Port field, enter 30016, for External Listen Address, enter <Master IP>, and for External Listen Port, enter 30016. Leave the Listen Address field blank.
  7. Click Finish to create the network channel for the dynamic cluster.

Note:

When WebLogic Server and Helidon are part of the same Kubernetes cluster, you can use the Fully Qualified Kubernetes Service Name as part of the public IP address.

Example of the FQDN name for the Administration Server:
wls-domain-admin-server.wls-domain-ns.svc.cluster.local
Example of the FQDN name for the dynamic cluster:
wls-domain-managed-server${id}.wls-domain-ns.svc.cluster.local
Creating the T3/T3S Channel Using the WLST Script
The following example script creates the T3 channel called admin-t3-channel that has a listen port 30014 and a public port 30014:
import sys
 
admin_server = sys.argv[1]
admin_port = sys.argv[2]
user_name = sys.argv[3]
password = sys.argv[4]
domain_ns = sys.argv[5]
 
connect(user_name, password, 't3://' + admin_server + ':' + admin_port)
 
edit()
startEdit()
cd('/')
 
print('Create channel for admin server')
cd('/Servers/admin-server')
cmo.createNetworkAccessPoint('admin-t3-channel')
cd('NetworkAccessPoints/admin-t3-channel')
cmo.setProtocol('t3')
cmo.setListenPort(30014)
cmo.setPublicPort(30014)
##You need to use public IP address when Helidon and WebLogic Server are in different Kubernetes clusters.
cmo.setPublicAddress('wls-domain-admin-server.' + domain_ns + '.svc.cluster.local')
print('admin-t3-channel added')
 
print('Create channel for cluster')
cd('/ServerTemplates/server-template_1')
cmo.createNetworkAccessPoint('cluster-t3-channel')
cd('/ServerTemplates/server-template_1/NetworkAccessPoints/cluster-t3-channel')
cmo.setProtocol('t3')
cmo.setListenPort(30016)
##You need to use public IP address when Helidon and WebLogic Server are in different Kubernetes.
cmo.setPublicAddress('wls-domain-managed-server${id}.' + domain_ns + '.svc.cluster.local')
cmo.setEnabled(true)
cmo.setHttpEnabledForThisProtocol(true)
cmo.setTunnelingEnabled(false)
cmo.setOutboundEnabled(false)
cmo.setTwoWaySSLEnabled(false)
cmo.setClientCertificateEnforced(false)
print('cluster-t3-channel added')
 
activate()
disconnect()
Creating the T3/T3S Channel Using WebLogic Deploy Tooling

You can create the T3/T3S channel resources by using WDT. The following example uses the WDT model configuration for creating the T3 channels for the Administration Server and the dynamic cluster:

topology:
    Server:
        admin-server:
            ListenAddress: wls-domain-admin-server
            NetworkAccessPoint:
                internal-t3:
                    ListenAddress: localhost
                    ListenPort: 7001
                admin-t3-channel:
                    # You need to use public IP address when Helidon and WebLogic Server are in different Kubernetes.
                    PublicAddress: wls-domain-admin-server.wls-domain-ns.svc.cluster.local
                    ListenPort: 30014
                    PublicPort: 30014
    ServerTemplate:
        server-template_1:
            Cluster: cluster-1
            ListenAddress: wls-domain-managed-server${id}
            ListenPort: 8001
            NetworkAccessPoint:
                cluster-t3-channel:
                    # You need to use public IP address when Helidon and WebLogic Server are in different Kubernetes clusters.
                    PublicAddress: wls-domain-managed-server${id}.wls-domain-ns.svc.cluster.local
                    ListenPort: 30016

Creating the Kubernetes Service for T3/T3S Channel for Communication

After you create the T3/T3S channels in the WebLogic Server domain, you should enable the channel for communication in the Kubernetes cluster. The following is an example of creating the Kubernetes service for T3 communication:

apiVersion: v1
kind: Service
metadata:
   name: adminserver-t3-external
   namespace: wls-domain-ns
   labels:
     weblogic.serverName: admin-server
spec:
  type: NodePort
  selector:
    weblogic.serverName: admin-server
  ports:
  - name: t3adminport
    protocol: TCP
    port: 30014
    targetPort: 30014
    nodePort: 30014
---
apiVersion: v1
kind: Service
metadata:
   name: cluster-t3-external
   namespace: wls-domain-ns
   labels:
     weblogic.clusterName: cluster-1
spec:
  type: NodePort
  selector:
    weblogic.clusterName: cluster-1
  ports:
  - name: t3clusterport
    protocol: TCP
    port: 30016
    targetPort: 30016
    nodePort: 30016

Note:

With this sample code, you can refer the T3/T3S Kubernetes services by using the following sample URLs:
  • Refer the admin T3 external URL using t3://adminserver-t3-external.wls-domain-ns.svc.cluster.local:30014.
  • Refer the cluster T3 external URL using t3://cluster-t3-external.wls-domain-ns.svc.cluster.local:30016.

For information about external WebLogic clients in WebLogic Kubernetes Operator, see External WebLogic Clients.

Configuring the JMS Resources in WebLogic Server Using WebLogic Deploy Tooling

A simple example of a model to deploy the JMS resources by targeting them to the WebLogic Administration Server and the dynamic cluster using WDT.

resources:
    FileStore:
        FileStoreCluster:
            Target: cluster-1
            Directory: wlsdeploy/stores/FileStoreCluster/
        FileStoreAdmin:
            Target: admin-server
            Directory: wlsdeploy/stores/FileStoreAdmin/
    JMSServer:
        JMSServerCluster:
            Target: cluster-1
            PersistentStore: FileStoreCluster
        JMSServerAdmin:
            Target: admin-server
            PersistentStore: FileStoreAdmin
            JmsSessionPool:
                JMSSessionPool0: {}
    JMSSystemResource:
        jmsmodulecluster:
            Target: cluster-1
            SubDeployment:
                jmssdcluster:
                    Target: JMSServerCluster
            JmsResource:
                ConnectionFactory:
                    dqcf:
                        DefaultTargetingEnabled: true
                        JNDIName: dqcf
                        ClientParams:
                            MessagesMaximum: 1
                        LoadBalancingParams:
                            ServerAffinityEnabled: false
                        TransactionParams:
                            XAConnectionFactoryEnabled: true
                UniformDistributedQueue:
                    udq:
                        JNDIName: udq
                        SubDeploymentName: jmssdcluster
                        MessagingPerformancePreference: 0
                        DeliveryFailureParams:
                            RedeliveryLimit: 600
                        DeliveryParamsOverrides:
                            RedeliveryDelay: 1000
                            DeliveryMode: Persistent
        jmsmoduleadmin:
            Target: admin-server
            SubDeployment:
                jmssdadmin:
                    Target: JMSServerAdmin
            JmsResource:
                ConnectionFactory:
                    qcf:
                        DefaultTargetingEnabled: true
                        JNDIName: qcf
                        ClientParams:
                            MessagesMaximum: 1
                        LoadBalancingParams:
                            ServerAffinityEnabled: false
                        TransactionParams:
                            XAConnectionFactoryEnabled: true
                Queue:
                    queue:
                        JNDIName: queuejndi
                        SubDeploymentName: jmssdadmin
                        MessagingPerformancePreference: 0
                        DeliveryFailureParams:
                            RedeliveryLimit: 600
                        DeliveryParamsOverrides:
                            RedeliveryDelay: 1000
                            DeliveryMode: Persistent
                Topic:
                    myTopic:
                        JNDIName: myTopic
                        SubDeploymentName: jmssdadmin

Setting Up the JMS Integration with Helidon

Before you begin the integration steps, ensure that you have created the required JMS resources and the T3/T3S channels. For information about creating the T3/T3S channels, see Enabling the T3/T3S Channel in the WebLogic Kubernetes Operator. Set up the integration between WebLogic Server Java Message Service (JMS) and Helidon by adding the required dependencies in the pom.xml file and configuring the WebLogic Server JMS connector. These dependencies enable reactive streaming and messaging along with JMS.
To set up the integration:
  1. Add the following dependencies to the pom.xml file of Helidon:
    Dependency for Reactive Messaging
    <dependency>
       <groupId>io.helidon.microprofile.messaging</groupId>
       <artifactId>helidon-microprofile-messaging</artifactId>
    </dependency>
    Dependency for JMS Connector
    <dependency>
        <groupId>io.helidon.messaging.jms</groupId>
        <artifactId>helidon-messaging-jms</artifactId>
    </dependency>
    Dependency for Messaging Health
    <dependency>
        <groupId>io.helidon.microprofile.messaging</groupId>
        <artifactId>helidon-microprofile-messaging-health</artifactId>
    </dependency>

    Dependencies for the WLS Thin Client JAR File

    If you are using Helidon 3.x, add the jakarta thin client JAR file as part of the Maven compilation/runtime dependencies, as shown below:
    <dependency>
        <groupId>wlthint3client.jakarta</groupId>
        <artifactId>wlthint3client-jakarta</artifactId>
        <version>1.0</version>
    </dependency>
    The following example shows how you can add the jakarta thin client to the Maven repository:
    mvn install:install-file -Dfile=<JAR_FILE_PATH>/wlthint3client.jakarta.jar -DgroupId=wlthint3client.jakarta -DartifactId=wlthint3client-jakarta -Dversion=1.0
    If you are using Helidon 2.x, add the javax thin client JAR file as part of the Maven compilation/runtime dependencies, as shown below:
    <dependency>
        <groupId>wlthint3client</groupId>
        <artifactId>wlthint3client</artifactId>
        <version>1.0</version>
    </dependency>
    The following example shows how you can add the javax thin client to the Maven repository:
    mvn install:install-file -Dfile=<WLS_ORACLE_HOME>/wlserver/server/lib/wlthint3client.jar -DgroupId=wlthint3client -DartifactId=wlthint3client -Dversion=1.0

    Note:

    Ensure that the values for groupId, artifactId, and the version are identical to the values used in the mvn install:install-file command.
  2. Configure the Helidon JMS connector. For more information about the connector, see the following documents:

    The configuration includes the following information:

    • The JMS environment properties that are used to lookup resources on the WebLogic Server:
      • WLS INITIAL_CONTEXT_FACTORY (java.naming.factory.initial): weblogic.jms.WLInitialContextFactory
      • SECURITY_PRINCIPAL (java.naming.security.principal): The user name for WebLogic Server.
      • SECURITY_CREDENTIALS (java.naming.security.credentials): The password for WebLogic Server.
      • PROVIDER_URL (java.naming.provider.url): The WebLogic Server T3/T3S connection URL.
    • The JMS resource details for the following:
      • JMS connection factory
      • JMS destination
      • JMS destination type
    The following example shows the helidon-jms connector configurations added to the <src>/main/resources/application.yaml file. In this example, JMS clients use the Java Naming and Directory Interface (JNDI) naming service. Hence, this example uses the jndi.destination key to refer the JMS destination name instead of using the destination key.
    # User-defined properties
    wls-username: <wls_username>
    wls-password: <wls_password>
    # WLS Admin server t3 connection URL
    wls-admin-url: t3://localhost:7001
    # WLS Admin T3 Kubernetes Service URL format within the same kubernetes cluster
    # wls-admin-url: t3://adminserver-t3-external.wls-domain-ns.svc.cluster.local:30014
    # WLS Cluster t3 connection URL
    wls-cluster-url: t3://localhost:7003,localhost:7005,localhost:7007
    # WLS Cluster T3 Kubernetes Service URL format within same Kubernetes cluster
    # wls-cluster-url: t3://cluster-t3-external.wls-domain-ns.svc.cluster.local:30016
     
    mp:
      messaging:
        connector:
          helidon-jms:
            jndi:
               #Default connection factory name. This can be overridden in individual resource configurations
               jms-factory: qcf
               #JMS environment properties to lookup resources
               env-properties:
                  java.naming.factory.initial: weblogic.jms.WLInitialContextFactory
                  java.naming.provider.url: ${wls-admin-url}
                  java.naming.security.principal: ${wls-username}
                  java.naming.security.credentials: ${wls-password}
     
        # Add all consumer resources-related configurations below incoming. 
        incoming:
          #Identifier "from-wls-q" is used with the @Incoming annotation.
          from-wls-q:
            #Connector Name as specific in connector section. It is predefined.
            connector: helidon-jms
            #JMS Destination Name in JNDI format.
            jndi.destination: queuejndi
            #JMS Destination Type.
            type: queue
            #JMS Connection Factory.
            jndi.jms-factory: qcf
     
        # Add all producer resources-related configurations below outgoing. 
        outgoing:
          #Identifier "to-wls-q" is used with the @Outgoing annotation.
          to-wls-q:
            connector: helidon-jms
            jndi.destination: queuejndi
            type: queue
            jndi.jms-factory: qcf
    This is an example of the helidon-jms connector configurations for a distributed queue:
    mp:
      messaging:
        connector:
          helidon-jms:
            jndi:
               #Default connection factory name. This can be overridden in individual resource configurations.
               jms-factory: qcf
               #JMS environment properties to lookup resources.
               env-properties:
                  # Env properties
        outgoing:
          #Sample configurations for distributed queue.
          to-wls-dq:
            #Connector Name.
            connector: helidon-jms
            #JMS Dqueue JNDI Name.
            jndi.destination: dqcf
            type: queue
            #JMS DQueue Connection factory JNDI value.
            jndi.jms-factory: dqcf
            #Here wls-cluster-url refers to t3/t3s URL of WebLogic Cluster.
            #JMS DQueue provider URL. It Overrides the default provider value specified in the helidon-jms.jndi.env-properties section.
            jndi.env-properties.java.naming.provider.url: ${wls-cluster-url}

    Note:

    The helidon-jms connector can also be used with the Create Destination Identifier (CDI) naming service to look up the configured JMS objects. In this case, you should use the destination key to refer to the JMS destination name instead of using the jndi.destination key.
  3. After configuring the WebLogic Server JMS connector, add the Java code to send and receive messages to and from WebLogic Server.

    If you are using Helidon 3.x, you may use the following Java code example as reference:

    package helidon.examples.quickstart.mp;
    import org.eclipse.microprofile.reactive.messaging.Incoming;
    import org.eclipse.microprofile.reactive.messaging.Outgoing;
    import org.eclipse.microprofile.reactive.messaging.Channel;
    import org.eclipse.microprofile.reactive.messaging.Emitter;
    import jakarta.enterprise.context.ApplicationScoped;
    import jakarta.inject.Inject;
     
    @ApplicationScoped
    public class JMSQueue {
        //Inject channel to produce messages
        @Inject
        @Channel("to-wls-q")
        private Emitter<String> emitter;
     
        //Send Message 
        public void sendMessage(String msg) {
           emitter.send(msg);
        }
     
        //Sample script to consume Messages 
        @Incoming("from-wls-q")
        public void receive(String msg) {
            System.out.println("Process JMS message as per business logic"+msg);
        }
    }

    If you are using Helidon 2.x, you may use the following Java code example as reference:

    package helidon.examples.quickstart.mp;
    import org.reactivestreams.FlowAdapters;
    import org.reactivestreams.Publisher;
    import java.util.concurrent.SubmissionPublisher;
    import org.eclipse.microprofile.reactive.messaging.Incoming;
    import org.eclipse.microprofile.reactive.messaging.Outgoing;
    import javax.enterprise.context.ApplicationScoped;
     
    @ApplicationScoped
    public class JMSQueue {
        SubmissionPublisher<String> emitter = new SubmissionPublisher<>();
     
        //Register publisher
        @Outgoing("to-wls-q")
        public Publisher<String> registerPublisher() {
            return FlowAdapters.toPublisher(emitter);
        }
     
        //Send Messages
        public void sendMessage(String msg) {
            emitter.submit(msg);
        }
     
        //Sample Script To Consume Messages
        @Incoming("from-wls-q")
        public void receive(String msg) {
            System.out.println("Process JMS message as per business logic"+msg);
        }
    }
  4. (This step is applicable only for Helidon 3.x.) Add the serial-config.properties file in the <src>/main/resources/META-INF/helidon/ location with the following content to address the deserialization filter issue reported with Helidon JEP-290 Implementation.
    pattern=weblogic.**;java.util.**;java.lang.**;java.io.**;java.rmi.**;javax.naming.**;jakarta.jms.**

    For more information about deserialization filters, see JEP-290.

    Note:

    The suggested filter configuration helps only for selected use cases. In case of issues, you may need to use your own pattern that is suitable for your use case.
  5. Start the WebLogic Server if it is not already up and running. For information about starting the WebLogic domain in Kubernetes, see Preparing the Kubernetes Cluster for WebLogic Server and Helidon Integration.

    You should have also created the JMS resources (such as Queue, Topic, Uniform Distributed Queue, and so on) and the T3/T3S channels.

  6. Build the Helidon application using the following command:
    mvn clean package -DskipTests=true
  7. Run the Helidon application using the following command:
    java -jar target/<Helidion-Project-Name>.jar

Troubleshooting Common JMS Issues

Learn about the common issues you may encounter when setting up the integration between WebLogic Server and Helidon 3.x or 2.x.

Issue 1

The filter status: REJECTED error is reported with the latest Patch Set Updated (PSU) for the WebLogic Server thin client jar file. Here is a sample of the error message:

<Error> <RJVM> <WL-000503> <Incoming message header or abbreviation processing failed.
 java.io.InvalidClassException: filter status: REJECTED
        at java.base/java.io.ObjectInputStream.filterCheck(ObjectInputStream.java:1414)
        at java.base/java.io.ObjectInputStream.readNonProxyDesc(ObjectInputStream.java:2055)
        at java.base/java.io.ObjectInputStream.readClassDesc(ObjectInputStream.java:1909)
        at java.base/java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:2235)
        at java.base/java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1744)
        at java.base/java.io.ObjectInputStream.readObject(ObjectInputStream.java:514)
        at java.base/java.io.ObjectInputStream.readObject(ObjectInputStream.java:472)
        at thinClientClassLoader//weblogic.utils.io.FilteringObjectInputStream.readObjectValidated(FilteringObjectInputStream.java:177)
. . . .
>
023.02.04 13:57:10 INFO io.helidon.messaging.connectors.jms.JmsConnector Thread[main,5,main]: JMS Connector gracefully stopped.
Exception in thread "main" io.helidon.messaging.MessagingException: Error when preparing JNDI context.
        at io.helidon.messaging.connectors.jms.ConnectionContext.<init>(ConnectionContext.java:64)
        at io.helidon.messaging.connectors.jms.JmsConnector.getPublisherBuilder(JmsConnector.java:429)
. . . .

Solution:

This issue is reported due to the deserialization filters used in Helidon. Add the serial-config.properties file in the <src>/main/resources/META-INF/helidon/ location, with the following content to resolve the issue:

pattern=weblogic.**;java.util.**;java.lang.**;java.io.**;java.rmi.**;javax.naming.**;jakarta.jms.**

For more information about deserialization filters, see Helidon JEP-290 Implementation.

Note:

The suggested filter configuration helps only for selected use cases. In case of issues, you may need to use your own pattern that is suitable for your use case.

Issue 2

The Helidon 2.x application hangs when you create the JMS connector during server startup.

Solution:

Ensure that the jaxws-wlswss-client and wlthint3client jars are not used together. These jar files should not be used together.

Issue 3

In Helidon 3.x, class loader issues are reported with wlthint3client jar file. Here is a sample of the error message:

SEVERE: Default error handler: Unhandled exception encountered.
java.util.concurrent.ExecutionException: Unhandled 'cause' of this exception encountered.
        at io.helidon.webserver.RequestRouting$RoutedRequest.defaultHandler(RequestRouting.java:398)
. . . 
Caused by: java.lang.ExceptionInInitializerError
        at weblogic.utils.LocatorUtilities.getService(LocatorUtilities.java:37)
        at weblogic.jms.WLInitialContextFactory.getInitialContext(WLInitialContextFactory.java:124)
. . . 
Caused by: A MultiException has 2 exceptions.  They are:
1. java.lang.NoSuchMethodException: The class GlobalServiceLocator has no constructor marked @Inject and no zero argument constructor
2. java.lang.IllegalArgumentException: Errors were discovered while reifying SystemDescriptor(
        implementation=weblogic.server.GlobalServiceLocator
. . .
Caused by: java.lang.NoSuchMethodException: The class GlobalServiceLocator has no constructor marked @Inject and no zero argument constructor
        at org.jvnet.hk2.internal.Utilities.findProducerConstructor(Utilities.java:1326)
. . .

Solution:

The thin client that uses the javax namespace does not work with Helidon 3.x that uses the jakarta namespace. Therefore, download the jakarta thin client jar, wlthint3client.jakarta.jar, that uses the jakarta namespace and also handles multi-release jar files correctly. Add this jar to the local maven repository, build, and then run the application.

Issue 4

WebLogic Server JMS connector issues reported in Helidon 3.x.

Solution:

The new WebLogic Server connector initializes the InitialContextFactory interface within a different thread from the one which creates the destination. This feature makes the WebLogic Server's thread-based security unusable. See Understanding Thread-Based Security on Clients and Servers in Developing JMS Applications for Oracle WebLogic Server. The solution for resolving these issues is to switch to object-based security. See Understanding Object-Based Security in Developing JMS Applications for Oracle WebLogic Server.

Issue 5

Helidon serialization config filter does not trace the actual rejected classes by default. Here is a sample of the error message you will find in the logs:

java.io.InvalidClassException: filter status: REJECTED

Solution:

To find out which class has been actually rejected, set the helidon.serialFilter.trace system property to either basic or full.
java -Dhelidon.serialFilter.trace=basic -jar ./target/custom-mp.jar

Each accepted or rejected class is logged only once with the basic trace filter setting.

ALLOWED class: class java.util.LinkedList, arrayLength: -1, depth: 2, references: 3, streamBytes: 84
REJECTED class: class java.util.ArrayList, arrayLength: -1, depth: 2, references: 3, streamBytes: 90

You can compose proper serialization filter pattern with the list of REJECTED classes.