Out of curiosity I'd like to build a simple websockets tyrus server chat project with javac and libraries in -classpath.
Yes, I know that this is not the standard way (mvn is), but I'm doing it as a proof of concept. I manage to get project built but it throws a NullPointerException
Code is:
ChatMain.java:
package chat;
import java.io.IOException;
import java.util.Collections;
import java.util.Map;
import javax.websocket.DeploymentException;
import org.glassfish.tyrus.server.Server;
public class ChatMain {
public static void main(String[] args) throws DeploymentException,
IOException {
Map<String, Object> properties = Collections.emptyMap();
Server server = new Server("localhost", 8080, "/ws", properties,
ChatEndPoint.class);
System.out.println(server);
try {
server.start();
System.in.read();
} finally {
server.stop();
}
}
}
ChatEndPoint.java:
package chat;
import java.io.IOException;
import java.util.Map;
import java.util.HashMap;
import java.util.Collections;
import javax.websocket.OnClose;
import javax.websocket.OnMessage;
import javax.websocket.OnOpen;
import javax.websocket.Session;
import javax.websocket.server.ServerEndpoint;
import org.json.*;
#ServerEndpoint("/chat")
public class ChatEndPoint {
private static Map<String, Session> peers = Collections.synchronizedMap(new HashMap<String, Session>());
#OnOpen
public void onOpen(Session peer) {
System.out.println("onOpen");
}
#OnMessage
public void onMessage(String message, Session peer) throws IOException {
System.out.println("onMessage");
JSONObject json = new JSONObject(message);
String nick = (String) json.get("nick");
boolean newClient = json.has("action") && ((String) json.get("action")).equals("add");
synchronized(peers) {
// Iterate over the connected sessions
// and broadcast the received message
for (Map.Entry<String, Session> entry : peers.entrySet()) {
if (newClient) {
JSONObject json1 = new JSONObject(json, new String[] { "action" }).put("nick", entry.getKey());
peer.getBasicRemote().sendText(json1.toString());
}
entry.getValue().getBasicRemote().sendText(message);
}
}
if (newClient)
peers.put(nick, peer);
}
#OnClose
public void onClose(Session peer) {
System.out.println("onClose");
peers.values().remove(peer);
}
}
javac line:
javac -cp chat/javax.websocket-api-1.1.jar:chat/tyrus-server-1.12.jar:chat/tyrus-spi-1.12.jar:chat/tyrus-core-1.12.jar:chat/grizzly-framework-2.3.22.jar:chat/grizzly-http-server-2.3.22.jar:chat/tyrus-container-grizzly-server-1.12.jar:chat/json.jar: chat/ChatMain.java
java line:
java -cp chat/javax.websocket-api-1.1.jar:chat/tyrus-server-1.12.jar:chat/tyrus-spi-1.12.jar:chat/tyrus-core-1.12.jar:chat/grizzly-framework-2.3.22.jar:chat/grizzly-http-server-2.3.22.jar:chat/tyrus-container-grizzly-server-1.12.jar:chat/json.jar: chat.ChatMain
runtime error:
Exception in thread "main" java.lang.NullPointerException
at org.glassfish.tyrus.container.grizzly.server.GrizzlyServerContainer$1.stop(GrizzlyServerContainer.java:228)
at org.glassfish.tyrus.server.Server.stop(Server.java:231)
at chat.ChatMain.main(ChatMain.java:23)
I understand that this can be done
Interestingly, more libraries are needed. If I include all libraries in websocket-ri-archive-1.12.zip bundle, it works well. Definitely, a builder is the way to go
Related
I am trying to connect to the code I have wrote through my browser, but unfortunately can not figure out how to do so. I have tried 127.0.0.1/hash but it did not work even though I have build the project using maven build compile. was wondering if someone could tell me what am I doing wrong here.
here is the code :
package com.snhu.sslserver;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.math.BigInteger;
import java.nio.charset.StandardCharsets;
#SpringBootApplication
public class ServerApplication {
public static void main(String[] args) {
SpringApplication.run(ServerApplication.class, args);
}
}
#RestController
class ServerController{
public static String calculateHash(String name) throws NoSuchAlgorithmException
{
MessageDigest md = MessageDigest.getInstance("SHA-256");
byte[] hash = md.digest(name.getBytes(StandardCharsets.UTF_8));
BigInteger number = new BigInteger(1, hash);
StringBuilder hexString = new StringBuilder(number.toString(16));
while (hexString.length() < 32)
{
hexString.insert(0, '0');
}
return hexString.toString();
}
#RequestMapping("/hash")
public String myHash() throws NoSuchAlgorithmException{
String data = "Hello Kamran Khosravi!";
String hash = calculateHash(data);
return "<p>data:"+data+" : SHA-256 "+" : "+hash;
}
}
you can just replace the port 8080 with respective to your port number which you have in application.properties
Command : spring-boot:run
http://localhost:8080/hash
I am facing issue while testing kafka with camel. I used Embedded kafka with camel and here's what I tried
I have tried this example which tells us about testing kafka using embedded kafka
https://codenotfound.com/spring-kafka-embedded-unit-test-example.html
package com.codenotfound.kafka.producer;
import static org.assertj.core.api.Assertions.assertThat;
import static org.junit.Assert.assertThat;
import static org.springframework.kafka.test.assertj.KafkaConditions.key;
import static org.springframework.kafka.test.hamcrest.KafkaMatchers.hasValue;
import java.util.Map;
import java.util.Map.Entry;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.TimeUnit;
import org.apache.camel.builder.RouteBuilder;
import org.apache.camel.main.Main;
import org.apache.kafka.clients.consumer.ConsumerRecord;
import org.junit.After;
import org.junit.Before;
import org.junit.ClassRule;
import org.junit.Ignore;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.kafka.core.DefaultKafkaConsumerFactory;
import org.springframework.kafka.listener.ContainerProperties;
import org.springframework.kafka.listener.KafkaMessageListenerContainer;
import org.springframework.kafka.listener.MessageListener;
import org.springframework.kafka.test.rule.EmbeddedKafkaRule;
import org.springframework.kafka.test.utils.ContainerTestUtils;
import org.springframework.kafka.test.utils.KafkaTestUtils;
import org.springframework.test.annotation.DirtiesContext;
import org.springframework.test.context.junit4.SpringRunner;
#RunWith(SpringRunner.class)
#SpringBootTest
#DirtiesContext
public class SpringKafkaSenderTest {
private static final Logger LOGGER = LoggerFactory.getLogger(SpringKafkaSenderTest.class);
private static String SENDER_TOPIC = "sender.t";
#Autowired
private Sender sender;
private KafkaMessageListenerContainer<String, String> container;
private BlockingQueue<ConsumerRecord<String, String>> records;
Object groupId;
Object bootstrapServers;
#ClassRule
public static EmbeddedKafkaRule embeddedKafka = new EmbeddedKafkaRule(1, true, SENDER_TOPIC);
#Before
public void setUp() throws Exception {
// set up the Kafka consumer properties
Map<String, Object> consumerProperties = KafkaTestUtils.consumerProps("sender", "false",
embeddedKafka.getEmbeddedKafka());
for (Entry<String, Object> entry : consumerProperties.entrySet()) {
System.out.println("Key = " + entry.getKey() + ", Value = " + entry.getValue());
if (entry.getKey().equals("group.id")) {
groupId = entry.getValue();
} else if (entry.getKey().equals("bootstrap.servers")) {
bootstrapServers = entry.getValue();
}
}
// create a Kafka consumer factory
DefaultKafkaConsumerFactory<String, String> consumerFactory = new DefaultKafkaConsumerFactory<String, String>(
consumerProperties);
// set the topic that needs to be consumed
ContainerProperties containerProperties = new ContainerProperties(SENDER_TOPIC);
// create a Kafka MessageListenerContainer
container = new KafkaMessageListenerContainer<>(consumerFactory, containerProperties);
// create a thread safe queue to store the received message
records = new LinkedBlockingQueue<>();
// setup a Kafka message listener
container.setupMessageListener(new MessageListener<String, String>() {
#Override
public void onMessage(ConsumerRecord<String, String> record) {
LOGGER.debug("test-listener received message='{}'", record.toString());
records.add(record);
}
});
// start the container and underlying message listener
container.start();
// wait until the container has the required number of assigned partitions
ContainerTestUtils.waitForAssignment(container, embeddedKafka.getEmbeddedKafka().getPartitionsPerTopic());
}
#After
public void tearDown() {
// stop the container
container.stop();
}
#Test
public void testCamelWithKafka() throws Exception {
String topicName = "topic=javainuse-topic";
String kafkaServer = "kafka:localhost:9092";
String zooKeeperHost = "zookeeperHost=localhost&zookeeperPort=2181";
String serializerClass = "serializerClass=kafka.serializer.StringEncoder";
String toKafka = new StringBuilder().append(kafkaServer).append("?").append(topicName).append("&")
.append(zooKeeperHost).append("&").append(serializerClass).toString();
String embedded = new StringBuilder().append(bootstrapServers).append("?").append(topicName).append("&")
// .append(embeddedKafka.getEmbeddedKafka().getZookeeperConnectionString())
.append(zooKeeperHost).append("&").append(serializerClass).toString();
Main main = new Main();
main.addRouteBuilder(new RouteBuilder() {
#Override
public void configure() throws Exception {
from("file:D://inbox//?noop=true").split().tokenize("\n").to("direct:embedded");
}
});
main.run();
ConsumerRecord<String, String> received =
records.poll(10, TimeUnit.SECONDS);
// assertThat(received, hasValue(greeting));
// AssertJ Condition to check the key
// assertThat(received).has(key(null));
// System.out.println(received);
}
}
Camel should able to read from a file and move the data to kafka and consumer should able to read it.
You can use the #Runwith(CamelSpringBootRunner.class) to run the test case.
I'm very new to Drools and adapted the Spring Boot configuration i found here to enable me to read a bunch of rules from a Database as String's instead of reading them from DRL Files in an application folder.
When I startup my application using the code below i'm get the following exception using Spring Boot, Drools 6.5.Final, Java 1.8:
Caused by: java.lang.RuntimeException: Resource does not have neither
a source nor a target path. Impossible to add it to the bundle. Please
set either the source or target name of the resource before adding
it.null at
org.drools.compiler.kie.builder.impl.KieFileSystemImpl.write(KieFileSystemImpl.java:95)
~[drools-compiler-6.5.0.Final.jar:6.5.0.Final]
package com.example.demo;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.List;
import org.kie.api.KieBase;
import org.kie.api.KieServices;
import org.kie.api.builder.KieBuilder;
import org.kie.api.builder.KieFileSystem;
import org.kie.api.builder.KieModule;
import org.kie.api.builder.KieRepository;
import org.kie.api.builder.ReleaseId;
import org.kie.api.io.Resource;
import org.kie.api.runtime.KieContainer;
import org.kie.api.runtime.KieSession;
import org.kie.internal.io.ResourceFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
#Configuration
public class DroolsDatabaseConfig {
#Autowired
private DataService dataService;
#Bean
public KieFileSystem kieFileSystem() throws IOException {
KieFileSystem kieFileSystem = getKieServices().newKieFileSystem();
for (Resource resource : getRulesFromDB()) {
kieFileSystem.write(resource);
}
return kieFileSystem;
}
private List<Resource> getRulesFromDB() throws IOException {
List<Resource> resources = new ArrayList<Resource>();
List<String> rules = dataService.getRulesFromDB();
for (String rule : rules){
Resource r = ResourceFactory.newInputStreamResource(new ByteArrayInputStream(rule.getBytes(StandardCharsets.UTF_8)));
resources.add(r);
}
return resources;
}
#Bean
public KieContainer kieContainer() throws IOException {
final KieRepository kieRepository = getKieServices().getRepository();
kieRepository.addKieModule(new KieModule() {
public ReleaseId getReleaseId() {
return kieRepository.getDefaultReleaseId();
}
});
KieBuilder kieBuilder = getKieServices().newKieBuilder(kieFileSystem());
kieBuilder.buildAll();
return getKieServices().newKieContainer(kieRepository.getDefaultReleaseId());
}
private KieServices getKieServices() {
return KieServices.Factory.get();
}
#Bean
public KieBase kieBase() throws IOException {
return kieContainer().getKieBase();
}
#Bean
public KieSession kieSession() throws IOException {
return kieContainer().newKieSession();
}
}
Any ideas on how i can resolve this to allow me load the Rules from a String?
Thanks in advance
Below is the example i tried for websocket,
import java.io.IOException;
import java.util.Queue;
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import javax.websocket.OnClose;
import javax.websocket.OnError;
import javax.websocket.OnMessage;
import javax.websocket.OnOpen;
import javax.websocket.Session;
import javax.websocket.server.ServerEndpoint;
#ServerEndpoint("/socket")
public class ExampleWebSocket {
private static Queue<Session> queue = new ConcurrentLinkedQueue<Session>();
#OnMessage
public void onMessage(Session session, String msg) {
try {
System.out.println("received msg "+msg+" from "+session.getId());
ExecutorService executorService = Executors
.newFixedThreadPool(1);
ThreadClass newThread = new ThreadClass(session); // a thread class which is going to perform async operations
Future<String> fut = executorService.submit(newThread);
int i =10;
while(fut.isDone()){
if(i > 50){
fut.cancel(true);
return;
}
Thread.sleep(1000);
i++;
}
executorService.shutdown();
} catch (Exception e) {
e.printStackTrace();
}
}
#OnOpen
public void open(Session session) {
queue.add(session);
System.out.println("New session opened: "+session.getId());
}
#OnError
public void error(Session session, Throwable t) {
queue.remove(session);
System.err.println("Error on session "+session.getId());
}
#OnClose
public void closedConnection(Session session) throws IOException {
queue.remove(session);
System.out.println("session closed: "+session.getId());
}
}
I added the below dependency in my jar,
<dependency>
<groupId>javax.websocket</groupId>
<artifactId>javax.websocket-api</artifactId>
<version>1.1</version>
</dependency>
For this example, i am always getting 404 when i tried to hit from browser.
Our project also runs with spring 3.2. Do i have to add this class config in any xml files like we.xml.. I am totally stuck here.
Also i tried by adding <scope>provided</scope> in the dependency of javax.websocket-api then deployment getting failed with class not found exception.
Websocket is not supported by servers of lower version.
Below RUL provide us the list of websocket supported web servers.
https://github.com/Atmosphere/atmosphere/wiki/Supported-WebServers-and-Browsers
Spring JMS is working against me, as the title say I get a NoClassDefFoundError, below you find the code.
import javax.jms.ConnectionFactory;
import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.Queue;
import javax.jms.Session;
import org.springframework.jms.core.JmsTemplate;
import org.springframework.jms.core.JmsTemplate102;
import org.springframework.jms.core.MessageCreator;
public class JMSQueueSender {
private JmsTemplate jmsTemplate;
private Queue queue;
public void setConnectionFactory(ConnectionFactory cf) {
this.jmsTemplate = new JmsTemplate102(cf, false);
}
public void setQueue(Queue queue) {
this.queue = queue;
}
public void simpleSend() throws Exception {
this.jmsTemplate.send(this.queue, new MessageCreator() {
public Message createMessage(Session session) throws JMSException {
return session.createTextMessage("hello queue world");
}
});
}
}
This is also the example code, I have a working code with IBM, but I'm trying to change it for a Spring JMS, but it isn't working. Can someone help me.
I guess you need to add spring-tx.jar (or org.springframework.transaction-*.jar with new style of names) to the classpath.
Try checking your JAVA_HOME and CLASSPATH settings.