Reputation: 547
I am trying to execute apache pulsar producer and consumer program through java, I installed apache-pulsar standalone in GCP virtual machine and started the cluster in standalone mode. Next step is I had given a maven build in windows eclipse and same jar file I uploaded in GCP machine When I am executing producer and consumer program in windows eclipse I am getting connection refused error which is obvious because pulsar is not installed in windows machine. But when I am trying same thing in GCP instance even cluster is already started I am getting error which is related to no class def found error.
pom.xml >>>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>pulsar-client-project</groupId>
<artifactId>pulsar-client-project</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>pulsar-client-project</name>
<url>http://maven.apache.org</url>
<properties>
<java.version>1.8</java.version>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
</properties>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>3.8.1</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.apache.pulsar</groupId>
<artifactId>pulsar-client</artifactId>
<version>2.0.1-incubating</version>
</dependency>
</dependencies>
</project>
ProducerTutorial.java >>>
package pulsar_client_project.pulsar_client_project;
import org.apache.pulsar.client.api.CompressionType;
import org.apache.pulsar.client.api.Message;
import org.apache.pulsar.client.api.MessageBuilder;
import org.apache.pulsar.client.api.MessageId;
import org.apache.pulsar.client.api.Producer;
import org.apache.pulsar.client.api.PulsarClient;
import org.apache.pulsar.client.api.PulsarClientException;
//import org.slf4j.Logger;
//import org.slf4j.LoggerFactory;
import java.io.IOException;
import java.util.stream.IntStream;
public class ProducerTutorial {
// private static final Logger log =
LoggerFactory.getLogger(ProducerTutorial.class);
private static final String SERVICE_URL = "pulsar://localhost:6650";
private static final String TOPIC_NAME = "my-topic";
public static void main(String[] args) throws IOException {
System.out.println("inside main");
// Create a Pulsar client instance. A single instance can be shared across many
// producers and consumer within the same application
PulsarClient client = PulsarClient.builder()
.serviceUrl(SERVICE_URL)
.build();
System.out.println("client.."+client);
// Here you get the chance to configure producer specific settings
Producer<byte[]> producer = client.newProducer()
// Set the topic
.topic(TOPIC_NAME)
// Enable compression
.compressionType(CompressionType.LZ4)
.create();
System.out.println("producer.."+producer);
// Once the producer is created, it can be used for the entire application life-cycle
// log.info("Created producer for the topic {}", TOPIC_NAME);
// Send 10 test messages
IntStream.range(1, 11).forEach(i -> {
String content = String.format("hello-pulsar-%d", i);
// Build a message object
Message<byte[]> msg = MessageBuilder.create()
.setContent(content.getBytes())
.build();
// Send each message and log message content and ID when successfully received
try {
MessageId msgId = producer.send(msg);
//log.info("Published message '{}' with the ID {}", content, msgId);
} catch (PulsarClientException e) {
//log.error(e.getMessage());
}
});
client.close();
}
}
ConsumerTutorial >>>>
package pulsar_client_project.pulsar_client_project;
import java.io.IOException;
import org.apache.pulsar.client.api.Consumer;
import org.apache.pulsar.client.api.Message;
import org.apache.pulsar.client.api.PulsarClient;
import org.apache.pulsar.client.api.SubscriptionType;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class ConsumerTutorial {
//private static final Logger log =
LoggerFactory.getLogger(ConsumerTutorial.class);
private static final String SERVICE_URL = "pulsar://localhost:6650";
private static final String TOPIC_NAME = "my-topic";
private static final String SUBSCRIPTION_NAME = "my-subscription";
public static void main(String[] args) throws IOException {
// Create a Pulsar client instance. A single instance can be shared
across many
// producers and consumer within the same application
System.out.println("inside main");
PulsarClient client = PulsarClient.builder()
.serviceUrl(SERVICE_URL)
.build();
System.out.println("client.."+client);
// Here you get the chance to configure consumer specific settings. eg:
Consumer<byte[]> consumer = client.newConsumer()
.topic(TOPIC_NAME)
// Allow multiple consumers to attach to the same subscription
// and get messages dispatched as a queue
.subscriptionType(SubscriptionType.Shared)
.subscriptionName(SUBSCRIPTION_NAME)
.subscribe();
System.out.println("consumer.."+consumer);
// Once the consumer is created, it can be used for the entire application lifecycle
//log.info("Created consumer for the topic {}", TOPIC_NAME);
do {
// Wait until a message is available
Message<byte[]> msg = consumer.receive();
// Extract the message as a printable string and then log
String content = new String(msg.getData());
// log.info("Received message '{}' with ID {}", content, msg.getMessageId());
// Acknowledge processing of the message so that it can be deleted
consumer.acknowledge(msg);
} while (true);
}
}
So, What is the appropriate solution for ubuntu/GCP VM machine. What I have done wrong, Please give me direction
Thanks in advance
Upvotes: 3
Views: 3704
Reputation: 5094
ClassNotFoundException means that the class is not found in your classpath.
When you run locally from Eclipse the pulsar-client classes are visible to the java process that is being summoned by Eclipse when you press the run button. However when you run the jar on the GCP machine you are not including classes from pulsar-client jar in your classpath and that is why they are missing:
java -cp pulsar-client-project-0.0.1-SNAPSHOT.jar pulsar_client_project.pulsar_client_project.ConsumerTutorial
The above command states that the classpath for the java process are standard JDK classes and the classes from the jar pulsar-client-project-0.0.1-SNAPSHOT
and the class to be ran (main-class) is pulsar_client_project.pulsar_client_project.ConsumerTutorial
.
What you need to do is provide a copy of pulsar-client jar on the GCP machine and include it in your classpath. E.g.
java -cp pulsar-client-project-0.0.1-SNAPSHOT.jar:pulsar-client.jar pulsar_client_project.pulsar_client_project.ConsumerTutorial
or
java -cp pulsar-client-project-0.0.1-SNAPSHOT.jar;pulsar-client.jar pulsar_client_project.pulsar_client_project.ConsumerTutorial
depending on the GCP machine operating system (:
is usually path separator on unix like operating systems whereas ;
is usually path separator on windows systems). Something similar is being done automatically by your Eclipse when running locally.
The potentially easier way to do that would be to include all project dependencies in the resulting jar file. If you modify your pom like this:
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>pulsar-client-project</groupId>
<artifactId>pulsar-client-project</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>pulsar-client-project</name>
<url>http://maven.apache.org</url>
<properties>
<java.version>1.8</java.version>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
</properties>
<dependencies>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-simple</artifactId>
<version>1.7.25</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>3.8.1</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.apache.pulsar</groupId>
<artifactId>pulsar-client</artifactId>
<version>2.0.1-incubating</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
<configuration>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
Here the assembly plugin is defined which will include all the dependencies in the resulting jar file target/pulsar-client-project-0.0.1-SNAPSHOT-jar-with-dependencies
. You can see that its size is ~25 MB whereas the original target/pulsar-client-project-0.0.1-SNAPSHOT.jar
is ~5KB. You can also open the jars with any zip capable archiver program (winzip, peazip, unzip...) and inspect their contents since the jar file format is built upon zip file format.
Now, when you copy the bigger jar file to GCP machine you should be able to run it like this:
java -cp pulsar-client-project-0.0.1-SNAPSHOT-jar-with-dependencies.jar pulsar_client_project.pulsar_client_project.ConsumerTutorial
or
java -cp pulsar-client-project-0.0.1-SNAPSHOT-jar-with-dependencies.jar pulsar_client_project.pulsar_client_project.ProducerTutorial
Upvotes: 4