Category Archives: Java - Page 5

Simple JMS Producer

Here is a JMS Producer template to use when I forget how to write them. It uses ActiveMQ as JMS provider and JNDI for connection propereties:

import javax.jms.Connection;
import javax.jms.ConnectionFactory;
import javax.jms.Destination;
import javax.jms.Message;
import javax.jms.MessageProducer;
import javax.jms.Session;
import javax.naming.InitialContext;

public class Producer {

    public static void main(String[] args) throws Exception {

        InitialContext context = new InitialContext();
        ConnectionFactory factory = 
                 (ConnectionFactory) context.lookup("ConnectionFactory");

        Connection connection = factory.createConnection();
        connection.start();

        // Start a non-transacted session for sending messages
        Session session = 
               connection.createSession(false, Session.AUTO_ACKNOWLEDGE);

        Destination destination = (Destination) context.lookup("test");
        MessageProducer consumer = session.createProducer(destination);

        // Create text message
        Message message = session.createTextMessage("Hello World");

        // Send 10 "Hello World" messages to queue
        for (int i = 0; i < 10; i++) {
            consumer.send(message);
        }

        // Clean up
        session.close();
        connection.close();
        context.close();

    }
}

jndi.properties:

java.naming.factory.initial = org.apache.activemq.jndi.ActiveMQInitialContextFactory

# Use the following property to configure the default connector
java.naming.provider.url = tcp://localhost:61616

# Register some queues in JNDI using the form
# queue.[jndiName] = [physicalName]
queue.test = NIKLAS.TEST

ActiveMQ Client lib dependency pom:

<dependency>
     <groupid>org.apache.activemq</groupid>
     <artifactid>activemq-client</artifactid>
     <version>5.7.0</version>
</dependency>

Tested on Windows 10, Maven 3.8.4, Java 11.0.18 and ActiveMQ Client 5.7.0

Simple transacted JMS consumer

Ever looked for a simple JMS Consumer template – here is one and it is transacted too 🙂

import javax.jms.Connection;
import javax.jms.ConnectionFactory;
import javax.jms.Destination;
import javax.jms.Message;
import javax.jms.MessageConsumer;
import javax.jms.Session;
import javax.naming.InitialContext;


public class Consumer {

    public static void main(String[] args) throws Exception {

        InitialContext context = new InitialContext();
        ConnectionFactory factory = 
                       (ConnectionFactory) context.lookup("ConnectionFactory");

        Connection connection = factory.createConnection();
        connection.start();

        // Start the transaction
        Session session = 
                    connection.createSession(true, Session.SESSION_TRANSACTED);

        Destination destination = (Destination) context.lookup("test");
        MessageConsumer consumer = session.createConsumer(destination);

        Message message;

        try {
            // Get all messages of the queue
            while ((message = consumer.receive(3000)) != null) {
                System.out.println("Message: " + message);
            }
            // All is well - commit transaction
            session.commit();

        } catch (Exception e) {
            e.printStackTrace();
            // Something is wrong - rollback transaction
            session.rollback();
        }

        // Cleanup
        session.close();
        connection.close();
        context.close();

    }
}

This solution depends on JNDI so here is the jndi.properties also:

java.naming.factory.initial = org.apache.activemq.jndi.ActiveMQInitialContextFactory

# Use the following property to configure the default connector
java.naming.provider.url = tcp://localhost:61616

# Register some queues in JNDI using the form
# queue.[jndiName] = [physicalName]
queue.test = NIKLAS.TEST

I’m using an ActiveMQ server as JMS provider which works good with the ActiveMQ client:
pom.xml

 
       
            org.apache.activemq
            activemq-client
            5.7.0
        

Tested on Windows 10, Maven 3.8.4, Java 11.0.18 and ActiveMQ Client 5.7.0

How to use SPNEGO negotiation with Curl

1. First we need to check that we have an SPNEGO compatible Curl installed:

$ curl -V
curl 7.81.0 (x86_64-w64-mingw32) libcurl/7.81.0 OpenSSL/1.1.1m (Schannel) zlib/1.2.11 brotli/1.0.9 zstd/1.5.2 libidn2/2.3.1 libssh2/1.10.0 nghttp2/1.46.0
Release-Date: 2022-01-05
Protocols: dict file ftp ftps gopher gophers http https imap imaps ldap ldaps mqtt pop3 pop3s rtsp scp sftp smb smbs smtp smtps telnet tftp
Features: alt-svc AsynchDNS brotli HSTS HTTP2 HTTPS-proxy IDN IPv6 Kerberos Largefile libz MultiSSL NTLM SPNEGO SSL SSPI TLS-SRP zstd

Here we can see that the SPNEGO feature is available

2. Next we need to create a credentials cache for Curl to use

kinit <username>
Password for <username>@<domain.com>: <password>

Here we create a “authentication token” and put it in a credentials cache för Curl, and any other program ie. SoapUI and others, to use. ‘username’ is the name of the user. This can be omitted, and if so the default user and domain (user that runs the command) will be used instead. The ‘kinit’ command will ask for the password associated with the user. After this has been inputed the token is created

3. After that we run Curl with the following options:

curl --negotiate -u : https://a-spnego-protected-site/data-i-want-to-access

–negotiate will trigger SPNEGO behaviour
-u is needed but is left blank. On some sites though I have had to put <domain\user> to get it to work
: should point to the SPNEGO protected resource we want to access
Curl will now use the token in the credentials cache to authenticate against the web resource

Troubleshooting commands:

klist - lists all current tokens with the expiry timestamps in the cache
kdestroy - remove a ticket from the credentials cache

Tested with Curl v7.81.0 in GitBash on a Windows 10 with Java 1.8.0_301