NullPointer exception while init of WebSocketClient - java

I am getting nullpointer exception on Connecting to a secured websocket.
PFB the exception:
Exception in thread "main" java.lang.NullPointerException
at org.eclipse.jetty.websocket.common.extensions.AbstractExtension.getName(AbstractExtension.java:90)
at org.eclipse.jetty.websocket.api.extensions.ExtensionFactory.<init>(ExtensionFactory.java:37)
at org.eclipse.jetty.websocket.common.extensions.WebSocketExtensionFactory.<init>(WebSocketExtensionFactory.java:40)
at org.eclipse.jetty.websocket.client.WebSocketClient.<init>(WebSocketClient.java:90)
at com.service.SecureClientSocket.main(SecureClientSocket.java:26)
PFB my code:
package com.service;
import java.net.URI;
import java.util.concurrent.Future;
import org.eclipse.jetty.util.ssl.SslContextFactory;
import org.eclipse.jetty.websocket.api.Session;
import org.eclipse.jetty.websocket.api.annotations.OnWebSocketClose;
import org.eclipse.jetty.websocket.api.annotations.OnWebSocketConnect;
import org.eclipse.jetty.websocket.api.annotations.OnWebSocketError;
import org.eclipse.jetty.websocket.api.annotations.OnWebSocketMessage;
import org.eclipse.jetty.websocket.api.annotations.WebSocket;
import org.eclipse.jetty.websocket.client.WebSocketClient;
#WebSocket
public class SecureClientSocket {
public static void main(String []args){
String url = "wss://qa.sockets.stackexchange.com/";
SslContextFactory sslContextFactory = new SslContextFactory();
sslContextFactory.setTrustAll(true); // The magic
WebSocketClient client = new WebSocketClient(sslContextFactory);
try
{
client.start();
SecureClientSocket socket = new SecureClientSocket();
Future<Session> fut = client.connect(socket,URI.create(url));
Session session = fut.get();
session.getRemote().sendString("Hello");
session.getRemote().sendString("155-questions-active");
}
catch (Throwable t)
{
System.out.println(t.getMessage());
}
}
#OnWebSocketConnect
public void onConnect(Session sess)
{
System.out.println("onConnect({})"+sess);
}
#OnWebSocketClose
public void onClose(int statusCode, String reason)
{
System.out.println("onClose({}, {})"+ statusCode+ reason);
}
#OnWebSocketError
public void onError(Throwable cause)
{
System.out.println(cause);
}
#OnWebSocketMessage
public void onMessage(String msg)
{
System.out.println("onMessage() - {}"+ msg);
}
}

Related

How to resolve "org.eclipse.jetty.websocket.api.MessageTooLargeException" for Java WebSocketStompClient

When I'm running a Java WebSocketStompClient, I got below error:
org.eclipse.jetty.websocket.api.MessageTooLargeException: Text message size [73728] exceeds maximum size [65536]
Sample code:
import org.apache.log4j.Logger;
import org.springframework.messaging.simp.stomp.StompFrameHandler;
import org.springframework.messaging.simp.stomp.StompHeaders;
import org.springframework.messaging.simp.stomp.StompSession;
import org.springframework.messaging.simp.stomp.StompSessionHandlerAdapter;
import org.springframework.util.concurrent.ListenableFuture;
import org.springframework.web.socket.WebSocketHttpHeaders;
import org.springframework.web.socket.client.WebSocketClient;
import org.springframework.web.socket.client.standard.StandardWebSocketClient;
import org.springframework.web.socket.messaging.WebSocketStompClient;
import org.springframework.web.socket.sockjs.client.SockJsClient;
import org.springframework.web.socket.sockjs.client.Transport;
import org.springframework.web.socket.sockjs.client.WebSocketTransport;
import org.springframework.web.socket.sockjs.frame.Jackson2SockJsMessageCodec;
import java.lang.reflect.Type;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.ExecutionException;
public class HelloClient {
private static Logger logger = Logger.getLogger(HelloClient.class);
StompSession session;
private final static WebSocketHttpHeaders headers = new WebSocketHttpHeaders();
public ListenableFuture<StompSession> connect() {
Transport webSocketTransport = new WebSocketTransport(new StandardWebSocketClient());
List<Transport> transports = Collections.singletonList(webSocketTransport);
SockJsClient sockJsClient = new SockJsClient(transports);
sockJsClient.setMessageCodec(new Jackson2SockJsMessageCodec());
WebSocketStompClient stompClient = new WebSocketStompClient(sockJsClient);
long[] hb = stompClient.getDefaultHeartbeat();
boolean en = stompClient.isDefaultHeartbeatEnabled();
long timeout = stompClient.getReceiptTimeLimit();
String url = "https://www.test.com";
return stompClient.connect(url, headers, new MyHandler());
}
public void subscribeMsg(StompSession stompSession) throws ExecutionException, InterruptedException {
stompSession.subscribe("/topic/test", new StompFrameHandler() {
public Type getPayloadType(StompHeaders stompHeaders) {
return byte[].class;
}
public void handleFrame(StompHeaders stompHeaders, Object o) {
logger.info("Received message " + new String((byte[]) o));
String response = new String((byte[]) o);
}
});
}
private class MyHandler extends StompSessionHandlerAdapter {
public void afterConnected(StompSession stompSession, StompHeaders stompHeaders) {
logger.info("Now connected");
session = stompSession;
}
}
public boolean isConnected() {
try {
Thread.sleep(500);
return session != null && session.isConnected();
} catch (Exception e) {
logger.warn("Error happens when checking connection status, ", e);
return false;
}
}
public static void main(String[] args) throws Exception {
HelloClient helloClient = new HelloClient();
ListenableFuture<StompSession> f = helloClient.connect();
StompSession stompSession = f.get();
helloClient.subscribeMsg(stompSession);
while (true) {
if (!helloClient.isConnected()) {
logger.info("wss diconnected ");
logger.info("need re-create ");
}
}
}
}
How to increase the limitation for a Java stomp websocket client? I found some not related answers How can I set max buffer size for web socket client(Jetty) in Java which are not suitable for stomp websocket client.
Also tried stompClient.setInboundMessageSizeLimit(Integer.MAX_VALUE); which doesn't work.

Dockerize rmi application

I'm new to Docker and I would like to put my rmi server on docker and to access it using the client which is local, on the laptop. When the server is not on docker the application works, however when it is on docker, I get a "Connection Refused" error. Below is the code for the server:
import org.modelmapper.ModelMapper;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.boot.web.servlet.support.SpringBootServletInitializer;
import org.springframework.context.annotation.Bean;
import org.springframework.validation.annotation.Validated;
import ro.tuc.ds2020.services.MedicationPlanService;
import ro.tuc.ds2020.servinterface.IMedicationService;
import java.rmi.AlreadyBoundException;
import java.rmi.RemoteException;
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;
import java.util.*;
#SpringBootApplication
#Validated
public class Ds2020Application extends SpringBootServletInitializer {
private int port;
// private Registry registry;
#Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
return application.sources(Ds2020Application.class);
}
public Ds2020Application() throws RemoteException{
this.port = 8889;
Registry registry = null;
try {
registry = LocateRegistry.createRegistry(this.port);
} catch (RemoteException e) {
e.printStackTrace();
}
try {
//MedicationPlanService is the stub // "name",stub
registry.bind(IMedicationService.class.getSimpleName(), new MedicationPlanService());
} catch (RemoteException e) {
e.printStackTrace();
} catch (AlreadyBoundException e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
TimeZone.setDefault(TimeZone.getTimeZone("UTC"));
try {
SpringApplication.run(Ds2020Application.class, args);
System.out.println("The server has started.");
} catch (Exception e) {
e.printStackTrace();
}
}
#Bean
public ModelMapper modelMapper() {
return new ModelMapper();
}
}
and client:
package ro.tuc.ds2020.controller;
import ro.tuc.ds2020.DTO.DrugPlanDTO;
import ro.tuc.ds2020.servinterface.IMedicationService;
import ro.tuc.ds2020.view.DisplayTable;
import java.rmi.NotBoundException;
import java.rmi.RemoteException;
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;
import java.sql.SQLException;
import java.text.ParseException;
import java.util.ArrayList;
public class ClientController {
private static IMedicationService iMedicationService;
private Registry registry;
private String serverAddress;
private int serverPort;
private DisplayTable displayTable;
public ClientController() throws RemoteException, NotBoundException, SQLException, ParseException {
this.serverAddress = "localhost";
this.serverPort = 8889;
String patientID="334975ea-c90d-4fd2-9a0b-9e2c9f0e4cb9";
//obtain the stub for the registry
registry = LocateRegistry.getRegistry(serverAddress, serverPort);
//obtain stub for remote object from server registry
iMedicationService = (IMedicationService) (registry.lookup(IMedicationService.class.getSimpleName()));
ArrayList<DrugPlanDTO> dto= iMedicationService.getAllMedicationPlans(patientID);
for (DrugPlanDTO drugplans:
dto) {
System.out.println((String)drugplans.getBegin_time());
}
this.displayTable=new DisplayTable(dto,patientID);
System.out.println("Finished");
}
public static void sendMessage(String drugPlanID,String patientID,String medicationName,String begin_time,String end_time) throws RemoteException, SQLException {
if (iMedicationService != null) {
iMedicationService.savePillTakenLog(drugPlanID,patientID,medicationName,begin_time,end_time);
System.out.println("Finished send message"+ patientID);
}
}
}
Im not sure how to bind the client to the server when dockerizing the application.
Docker compose:
version: '3'
services:
tomcat-db-api:
image: ds_a3
ports:
- "8889:8889"
rabbitmq-container:
image: rabbitmq:management
ports:
- 5672:5672
- 15672:15672
Try setting the: this.serverAddress="tomcat-db-api;" at your client.

Route file to Queue Apache Camel

I have a requirement to read a file from a folder and place it on a queue.
Here is the code I have:
import java.io.File;
import org.apache.camel.CamelContext;
import org.apache.camel.Exchange;
import org.apache.camel.LoggingLevel;
import org.apache.camel.Processor;
import org.apache.camel.builder.RouteBuilder;
import org.apache.camel.impl.DefaultCamelContext;
public class FileMove{
public static void main(final String[] arguments) {
final CamelContext camelContext = new DefaultCamelContext();
try {
camelContext.addRoutes(new RouteBuilder() {
#Override
public void configure() throws Exception {
from("file://E:/TestingWatch1/input?preMove=staging&move=.completed&scheduler=quartz2&scheduler.cron=00+*/1+*+1/1+*+?+*")
.routeId("testRoute").process(new Processor() {
#Override
public void process(Exchange msg) throws Exception {
File file = msg.getIn().getBody(File.class);
String file1 = msg.getIn().getBody(String.class);
System.out.println("" + file + file1);
}
}).
to("file://E:/TestingWatch1/output");
}
});
camelContext.start();
// Thread.sleep(10*60*1000);
// camelContext.stop();
} catch (Exception ex) {
ex.printStackTrace();
}
}
}
I am able to read the file and file contents, but I need to place it on the queue.
How do I move the file or file contents to queue using the Java DSL?
Thanks, I found the solution: Here is the code
import java.io.File;
import javax.jms.ConnectionFactory;
import org.apache.activemq.ActiveMQConnection;
import org.apache.activemq.ActiveMQConnectionFactory;
import org.apache.camel.CamelContext;
import org.apache.camel.Exchange;
import org.apache.camel.LoggingLevel;
import org.apache.camel.Processor;
import org.apache.camel.builder.RouteBuilder;
import org.apache.camel.component.jms.JmsComponent;
import org.apache.camel.impl.DefaultCamelContext;
public class CopyTest {
public static void main(final String[] arguments) {
final CamelContext camelContext = new DefaultCamelContext();
ConnectionFactory connectionFactory = new ActiveMQConnectionFactory("admin", "admin",
ActiveMQConnection.DEFAULT_BROKER_URL);
camelContext.addComponent("test-jms", JmsComponent.jmsComponentAutoAcknowledge(connectionFactory));
try {
camelContext.addRoutes(new RouteBuilder() {
#Override
public void configure() throws Exception {
from("file://E:/TestingWatch1/input?preMove=staging&move=.completed&scheduler=quartz2&scheduler.cron=00+*/1+*+1/1+*+?+*")
.routeId("testRoute").process(new Processor() {
#Override
public void process(Exchange msg) throws Exception {
File file = msg.getIn().getBody(File.class);
String file1 = msg.getIn().getBody(String.class);
System.out.println("" + file + file1);
}
}).to("test-jms:queue:testMQDestination").
to("file://E:/TestingWatch1/output");
}
});
camelContext.start();
// Thread.sleep(10*60*1000);
// camelContext.stop();
} catch (Exception ex) {
ex.printStackTrace();
}
}
}

Why my websocket example isn't working?

I have two files server.java and client.java. Basically there is no error or message like Client Connected, Connected to server, Message:..., etc.
But if i change localhost to something else client.java does give an error but if it's correct no error or response.
server.java has this:
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.IOException;
import java.util.ArrayList;
import javax.json.Json;
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;
import org.glassfish.tyrus.server.*;
#ServerEndpoint("/game")
public class socketServer{
public static void main(String[] args) {
new socketServer();
}
public socketServer() {
runServer();
}
public static void runServer() {
Server s = new Server("localhost", 8025, "/websockets", null, socketServer.class);
try {
s.start();
} catch (Exception e) {
throw new RuntimeException(e);
}
}
#OnMessage
public String onMessage(String message, Session s) throws IOException {
System.out.println("User input: " + message);
s.getBasicRemote().sendText("Hello world Mr. " + message);
return message;
}
#OnOpen
public void onOpen(Session s) throws IOException {
System.out.println("Client connected");
s.getBasicRemote().sendText("wtf");
}
#OnClose
public void onClose() {System.out.println("Connection closed");}
#OnError
public void handleError(Throwable t) {t.printStackTrace();}
}
client.java has this:
import java.net.URI;
import java.net.URISyntaxException;
import javax.websocket.CloseReason;
import javax.websocket.OnClose;
import javax.websocket.OnMessage;
import javax.websocket.ClientEndpoint;
import javax.websocket.OnOpen;
import javax.websocket.Session;
import javax.websocket.DeploymentException;
import org.glassfish.tyrus.client.ClientManager;
#ClientEndpoint
public class clientServer {
public static void main(String[] args) {
new clientServer();
}
public clientServer() {
ClientManager client = ClientManager.createClient();
try {
client.connectToServer(clientServer.class, new URI("ws://localhost:8025/websockets/game"));
} catch (Exception e) {
e.printStackTrace();
}
}
#OnOpen
public void onOpen(Session session) {
System.out.println("connected to server");
try {
session.getBasicRemote().sendText("start");
} catch (IOException e) {
throw new RuntimeException(e);
}
}
#OnMessage
public String onMessage(String message, Session session) {
return message;
}
#OnClose
public void onClose(Session session, CloseReason closeReason) {
System.out.println("Client: closed");
}
}
I guess server.java and client.java have to use the same host name. If you change the URI in client.java, for example, from "ws://localhost:8025/websockets/game" to "ws://myhost:8025/websockets/game", try to change the first argument of the constructor of Server from "localhost" to "myhost".

Migrating sendUpstream in Netty 4

I'm migrating from netty 3 to netty 4. I have a pipeline handler that acts as a classic filter, intercepting/handling noncompliant messages on the way, and shoveling compliant ones upstream.
Based on the documentation (http://netty.io/wiki/new-and-noteworthy.html), I expected to use ctx.fireInboundBufferUpdated() in lieu of ctx.sendUpStream() to relay inbound. However, I've found this doesn't work, but ChannelHandlerUtil.addToNextInboundBuffer() does. I'd love some guidance as to:
My confusion over the current docs assertion that ctx.sendUpstream -> ctx.fireInboundBufferUpdated and,
What is the best practice in this case, if different than what I've done below.
The code:
//The pipeline
public class ServerInitializer extends ChannelInitializer<SocketChannel> {
#Override
public void initChannel(SocketChannel ch) throws Exception {
ChannelPipeline p = ch.pipeline();
p.addLast("decoder", new HttpRequestDecoder());
p.addLast("encoder", new HttpResponseEncoder());
p.addLast("inbound", InboundHttpRequestFilter.INSTANCE);
p.addLast("handler", handlerClass.newInstance());
}
}
//The filter
public class InboundHttpRequestFilter extends
ChannelInboundMessageHandlerAdapter<Object> {
#Override
public void messageReceived(ChannelHandlerContext ctx, Object msg)
throws Exception {
... discard/handle as necessary …;
//ctx.fireInboundBufferUpdated(); - doesn't propagate upstream
ChannelHandlerUtil.addToNextInboundBuffer(ctx, msg); // sends upstream
}
}
Try this :
ctx.nextInboundMessageBuffer().add(msg)
Javadoc :
Interface ChannelHandlerContext
MessageBuf<Object> nextInboundMessageBuffer()
Return the MessageBuf of the next ChannelInboundMessageHandler in the pipeline.
Netty 4 Multiple Handler Example :
MultiHandlerServer.java
import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.handler.codec.LineBasedFrameDecoder;
import io.netty.handler.codec.string.StringDecoder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.nio.charset.Charset;
public class MultiHandlerServer {
private static final Logger logger = LoggerFactory.getLogger(MultiHandlerServer.class);
final int port;
public MultiHandlerServer(final int port) {
this.port = port;
}
public void run() throws InterruptedException {
final NioEventLoopGroup bossGroup = new NioEventLoopGroup();
final NioEventLoopGroup workerGroup = new NioEventLoopGroup();
try {
final ServerBootstrap serverBootstrap = new ServerBootstrap()
.group(bossGroup, workerGroup)
.channel(NioServerSocketChannel.class)
.childHandler(new ChannelInitializer<SocketChannel>() {
#Override
protected void initChannel(SocketChannel ch) throws Exception {
ch.pipeline().addLast(
new LineBasedFrameDecoder(8192),
new StringDecoder(Charset.forName("UTF-8")),
new MultiHandler01(), new MultiHandler02());
}
});
final ChannelFuture future = serverBootstrap.bind(port).sync();
future.channel().closeFuture().sync();
} finally {
bossGroup.shutdownGracefully();
workerGroup.shutdownGracefully();
}
}
public static void main(String[] args) throws InterruptedException {
final MultiHandlerServer client = new MultiHandlerServer(8080);
client.run();
}
}
MultiHandler01.java
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundMessageHandlerAdapter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
*/
class MultiHandler01 extends ChannelInboundMessageHandlerAdapter<String> {
private Logger logger = LoggerFactory.getLogger(MultiHandler01.class);
MultiHandler01() {
}
#Override
public void messageReceived(ChannelHandlerContext ctx, String msg) throws Exception {
logger.info(String.format("Handler01 receive message: %s", msg));
ctx.nextInboundMessageBuffer().add(msg);
ctx.fireInboundBufferUpdated();
}
#Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
logger.error("Exception caught: %s", ctx.channel().remoteAddress(), cause);
ctx.close();
}
}
MultiHandler02.java
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundMessageHandlerAdapter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
*/
class MultiHandler02 extends ChannelInboundMessageHandlerAdapter<String> {
private Logger logger = LoggerFactory.getLogger(MultiHandler02.class);
MultiHandler02() {
}
#Override
public void messageReceived(ChannelHandlerContext ctx, String msg) throws Exception {
logger.info(String.format("Handler02 receive message: %s", msg));
}
#Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
logger.error("Exception caught: %s", ctx.channel().remoteAddress(), cause);
ctx.close();
}
}

Categories

Resources