Search code examples
javaazure-eventhub

Getting Exception in thread "main" java.lang.NoClassDefFoundError: com/azure/core/util/ClientOptions


I am working on test automating azure event hub functions using java in eclipse.

I am trying to run the receiver application for EventHub functions.

Below is the output:

Exception in thread "main" java.lang.NoClassDefFoundError: com/azure/core/util/ClientOptions
        at com.azure.storage.blob.BlobContainerClientBuilder.<init>(BlobContainerClientBuilder.java:73)
        at AzureEventHubTest.Receiver.main(Receiver.java:44)
    Caused by: java.lang.ClassNotFoundException: com.azure.core.util.ClientOptions
        at java.net.URLClassLoader.findClass(Unknown Source)
        at java.lang.ClassLoader.loadClass(Unknown Source)
        at sun.misc.Launcher$AppClassLoader.loadClass(Unknown Source)
        at java.lang.ClassLoader.loadClass(Unknown Source)
        ... 2 more        

Here is the code:

package AzureEventHubTest;
            
import com.azure.messaging.eventhubs.EventHubClientBuilder;
import com.azure.messaging.eventhubs.EventProcessorClient;
import com.azure.messaging.eventhubs.EventProcessorClientBuilder;
import com.azure.messaging.eventhubs.checkpointstore.blob.BlobCheckpointStore;
import com.azure.messaging.eventhubs.models.ErrorContext;
import com.azure.messaging.eventhubs.models.EventContext;
import com.azure.storage.blob.BlobContainerAsyncClient;
import com.azure.storage.blob.BlobContainerClientBuilder;
import com.azure.messaging.eventhubs.checkpointstore.blob.*;
import java.util.function.Consumer;
import java.util.concurrent.TimeUnit;
import com.azure.core.util.*;
import com.microsoft.azure.eventhubs.ConnectionStringBuilder;
import com.microsoft.azure.eventhubs.EventData;
import com.microsoft.azure.eventhubs.EventHubClient;
import com.microsoft.azure.eventhubs.EventHubException;

public class  Receiver {
    private static final String EH_NAMESPACE_CONNECTION_STRING = "//test";
                                                                //sb://eqix-es-dev-eventhub.servicebus.windows.net/;SharedAccessKeyName=RootManageSharedAccessKey;SharedAccessKey=y3cVul6e5HRi4h30eFNwKBx3YLHaV+A7kQSX40TIeZc=";
    private static final String eventHubName = "//test";
    private static final String STORAGE_CONNECTION_STRING = "//test";
    private static final String STORAGE_CONTAINER_NAME = "//test";
    
    
    public static final java.util.function.Consumer<EventContext> PARTITION_PROCESSOR = eventContext -> {
         System.out.printf("Processing event from partition %s with sequence number %d with body: %s %n", 
                 eventContext.getPartitionContext().getPartitionId(), eventContext.getEventData().getSequenceNumber(), eventContext.getEventData().getBodyAsString());

            if (eventContext.getEventData().getSequenceNumber() % 10 == 0) {
                eventContext.updateCheckpoint();
            }
        };

        public static final java.util.function.Consumer<ErrorContext> ERROR_HANDLER = errorContext -> {
            System.out.printf("Error occurred in partition processor for partition %s, %s.%n",
                errorContext.getPartitionContext().getPartitionId(),
                errorContext.getThrowable());
        };

        public static void main(String[] args) throws Exception {
            BlobContainerAsyncClient blobContainerAsyncClient = new BlobContainerClientBuilder()
                .connectionString(STORAGE_CONNECTION_STRING)
                .containerName(STORAGE_CONTAINER_NAME)
                .buildAsyncClient();

            EventProcessorClientBuilder eventProcessorClientBuilder = new EventProcessorClientBuilder()
                .connectionString(EH_NAMESPACE_CONNECTION_STRING, eventHubName)
                .consumerGroup(EventHubClientBuilder.DEFAULT_CONSUMER_GROUP_NAME).processEvent(PARTITION_PROCESSOR)
                .processError(ERROR_HANDLER)
                .checkpointStore(new BlobCheckpointStore(blobContainerAsyncClient));

            EventProcessorClient eventProcessorClient = eventProcessorClientBuilder.buildEventProcessorClient();

            System.out.println("Starting event processor");
            eventProcessorClient.start();

            System.out.println("Press enter to stop.");
            System.in.read();

            System.out.println("Stopping event processor");
            eventProcessorClient.stop();
            System.out.println("Event processor stopped.");

            System.out.println("Exiting process");
        }
}

Can anyone please help me to know where am I going wrong? What is wrong with my code or if anything else? I am stuck due to this.

These are the added maven dependencies:

Included- azureeventhubs dependencies and other:

<dependencies>
    <dependency>
        <groupId>com.azure</groupId>
        <artifactId>azure-messaging-eventhubs-checkpointstore-blob</artifactId>
        <version>1.1.1</version>
    </dependency>
    <dependency>
        <groupId>com.azure</groupId>
        <artifactId>azure-messaging-eventhubs</artifactId>
        <version>5.1.1</version>
    </dependency>
    <dependency>
        <groupId>org.slf4j</groupId>
        <artifactId>slf4j-api</artifactId>
        <version>2.0.0-alpha1</version>
    </dependency>
    <dependency>
        <groupId>org.slf4j</groupId>
        <artifactId>slf4j-simple</artifactId>
        <version>2.0.0-alpha1</version>
        <scope>test</scope>
    </dependency>
    <dependency>
        <groupId>com.azure</groupId>
        <artifactId>azure-storage-blob</artifactId>
        <version>12.10.0</version>
    </dependency>
    <dependency>
        <groupId>org.testng</groupId>
        <artifactId>testng</artifactId>
        <version>7.3.0</version>
        <scope>test</scope>
    </dependency>
    <dependency>
        <groupId>com.microsoft.azure</groupId>
        <artifactId>azure-eventhubs</artifactId>
        <version>2.2.0</version>
    </dependency>
</dependencies>

Solution

  • ClientOptions was introduced in azure-core version 1.9.0 which is used in azure-storage-blob version 12.10.0.

    1.1.1 version of azure-messaging-eventhubs-checkpointstore-blob uses an older version of azure-core (1.5.1) which doesn't have ClientOptions. So, at runtime, the older version of azure-core is getting loaded resulting in NoClassDefFoundError when creating BlobContainer that tries to use ClientOptions class.

    So, if you upgrade azure-messaging-eventhubs-checkpointstore=blob to 1.5.0 and azure-messaging-eventhubs to 5.5.0, this issue will be resolved.

    As a side note, you can remove azure-storage-blob from your dependency list as azure-messaging-eventhubs-checkpointstore-blob transitively includes azure-storage-blob.