JAX-RS ChunkedOutput and ChunkedInput with Wildfly - java

please help make this simple example to deploy on Wildfly (preferred version 10.1.0).
Sample code:
import org.glassfish.jersey.server.ChunkedOutput;
import javax.ws.rs.*;
import java.io.*;
#Path("/numbers")
public class NumbersResource {
#GET
public ChunkedOutput<String> streamExample(){
final ChunkedOutput<String> output = new ChunkedOutput<String>(String.class);
new Thread() {
#Override
public void run() {
try {
for (int i = 0; i < 100000 ; i++){
output.write(i + " ");
}
} catch (IOException e){
e.printStackTrace();
} finally {
try {
output.close();
} catch (IOException e){
e.printStackTrace();
}
}
}
}.start();
return output;
}
}
(the snippet of code belongs to the author MEMORYNOTFOUND. I had added it here just in case the side is shut down for any reason)
I had made it deploy on GlassFish and everything is ok. But now, I need this functionality to be ported on Wildfly. And from the import
import org.glassfish.jersey.server.ChunkedOutput;
It seams that class ChunkedOutput belongs to GlassFish us functionality. In other words, is there something similar us functionality with the import from Wildfly jars or I don't know...?
P.S. Please provide a simple example, among the response.
Thanks in advance!

Use StreamingOutput instead:
#GET
#Produces(MediaType.TEXT_PLAIN)
#Path("/<your-path>")
public Response hello() {
StreamingOutput stream = new StreamingOutput() {
#Override
public void write(OutputStream os) throws IOException, WebApplicationException {
Writer writer = new BufferedWriter(new OutputStreamWriter(os));
for (...) {
writer.write(...);
}
writer.flush();
}
};
return Response.ok(stream).build();
}

Related

JSON Simple unexpected character?

Unexpected character () at position 0.
at org.json.simple.parser.Yylex.yylex(Yylex.java:610)
at org.json.simple.parser.JSONParser.nextToken(JSONParser.java:269)
at org.json.simple.parser.JSONParser.parse(JSONParser.java:118)
at org.json.simple.parser.JSONParser.parse(JSONParser.java:81)
at org.json.simple.parser.JSONParser.parse(JSONParser.java:75)
at net.ddns.coolpvp.Testing.main(Testing.java:22)
I was making a TCP Server on Java, it was receiving a json and it gave this error, but I checked and the first character is '{', how can I fix this? I have no clue. I would be very grateful if you could help meEDIT: The JSON is generated by .NET Framework in a C# Application and this is a JSON
{"Type":"level-info","LevelNumber":1}
This is how the C# Application is generating the JSON
Program.cs
using System;
using System.Text;
using System.Net.Sockets;
using System.IO;
namespace Testing
{
public static class Program
{
public static void Main(string[] args)
{
TcpClient client = new TcpClient();
client.Connect("localhost", 152);
StreamWriter writer = new StreamWriter(client.GetStream(), Encoding.UTF8) { AutoFlush = true };
writer.WriteLine(new RequestLevelInfo(1).ToJSONString());
client.Close();
Console.ReadKey(true);
}
}
}
RequestLevelInfo.cs
using System.Web.Script.Serialization;
namespace Testing
{
public class RequestLevelInfo
{
public string Type { get { return "level-info"; } }
public int LevelNumber { get; }
public RequestLevelInfo(int level)
{
LevelNumber = level;
}
public string ToJSONString()
{
return new JavaScriptSerializer().Serialize(this);
}
}
}
The Server is reading it using a BufferedReader using the readLine method
package testing;
import java.net.Socket;
import java.io.IOException;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.InetSocketAddress;
import org.json.simple.JSONObject;
import org.json.simple.parser.JSONParser;
import org.json.simple.parser.ParseException;
public class Testing {
public static void main(String[] args) {
try {
ServerSocket server = new ServerSocket();
server.bind(new InetSocketAddress(InetAddress.getByName("localhost"), 152));
Socket client = server.accept();
BufferedReader reader = new BufferedReader(new InputStreamReader(client.getInputStream(), "UTF-8"));
String dataReceived = reader.readLine();
JSONObject json = (JSONObject)new JSONParser().parse(dataReceived);
System.out.println(json.toJSONString());
client.close();
server.close();
} catch (IOException ex) {
ex.printStackTrace(System.err);
} catch (ParseException ex) {
ex.printStackTrace(System.err);
}
}
}
The problem is in your C# code: it's sending incorrect JSON.
You are using the Encoding.UTF8 object. This object includes an invisible and unnecessary "byte order marker" character, which the Java JSON parser does not understand. JSON "must not" use a byte order mark character: JSON Specification and usage of BOM/charset-encoding
The solution is to create your own instance of UTF8Encoding. For example:
UTF8Encoding jsonEncoding = new UTF8Encoding(false);
StreamWriter writer = new StreamWriter(client.GetStream(), jsonEncoding) { AutoFlush = true };
Hello, I thought about your code and changed something, here is my code:
public static void main(String[] args) {
try {
BufferedReader bufferedReader = java.nio.file.Files.newBufferedReader(Paths.get("test.json"));
JSONObject data = (JSONObject) new JSONParser().parse(bufferedReader);
System.out.println(data.get("Type"));
} catch (Exception e) {
e.printStackTrace();
}
}
This is the content of the test.json File:
{"Type":"level-info","LevelNumber":1}
My output is: level-info
Please check if you really have org.json.simple.JSONObject, org.json.simple.parser.JSONParser and org.json.simple.parser.ParseException imported.
Not that you accidentally imported anything else.
Have fun, I hope I could help you!
EDIT
So, for me the error occurred with the following example:
public static void main(String[] args) {
try {
String string = "{name=Asel, number1=40.34, number2=29.343}";
JSONObject object = (JSONObject) new JSONParser().parse(string);
System.out.println(object.get("name"));
} catch (Exception e) {
e.printStackTrace();
}
}
But not with this:
public static void main(String[] args) {
try {
String string = "{\"name\":\"Asel\", \"number1\":\"40.34\", \"number2\":\"29.343\"}";
JSONObject object = (JSONObject) new JSONParser().parse(string);
System.out.println(object.get("name"));
} catch (Exception e) {
e.printStackTrace();
}
}
Therefore I wonder if your string that you really get from your TCP socket is exactly {"Type":"level-info","LevelNumber":"1"} and not something wrong liek this: {"Type"="level-info","LevelNumber"="1"}
To test it you could try to replace = with : in the string of TPC Socket and see if the error still occurs.
JSONObject json = (JSONObject)new JSONParser().parse(dataReceived.replace("=", ":"));

I want to read the output from the console

After a long period of searching for my problem, I have no other idea, I have to ask here.
I search for a method to read the console output or System.out to a JavaFX TextArea but I don't know how I get those strings.
I want to put that into an external Thread:
package Threads;
import Core.Engine;
import java.io.ByteArrayOutputStream;
import java.io.PrintStream;
import java.util.Scanner;
public class ConsoleListenerThread implements Runnable {
Engine engine;
public ConsoleListenerThread(Engine engine) {
this.engine = engine;
}
#Override
public void run() {
String line;
while (true){
}
}
}
Update:
I really need the console output...what you see when you start a program. And how I get there is unnecessary I think (Startup etx), because I just want a String whenever the console prints a new output.
Example:
System.out.println("Hello");
And then my thread revive this string:
"hello"
If you are printing directly to the console with the System.out.println() method, then you already have the string. If , on the other hand, you are calling a different method that prints to the console from another object, try having that method return a String instead so that you can store that data.
So I solved this problem, so here is the code:
package Threads;
import Core.Engine;
import java.io.*;
public class ConsolListenerThrad implements Runnable {
Engine engine;
public ConsolListenerThrad(Engine engine) {
this.engine = engine;
}
#Override
public void run() {
String line = null;
PipedOutputStream pOut = new PipedOutputStream();
System.setOut(new PrintStream(pOut));
PipedInputStream pIn = null;
try {
pIn = new PipedInputStream(pOut);
} catch (IOException e) {
e.printStackTrace();
}
BufferedReader reader = new BufferedReader(new InputStreamReader(pIn));
while (true){
try {
line = reader.readLine();
} catch (IOException e) {
e.printStackTrace();
}
engine.printConsollogOnGui(line);
}
}
}

Sending iDOC from Java to SAP

We have iDOC files that are generated from our system. Now we are trying to send them to SAP via RFC connection. I already etablished an RFC connection AS A CLIENT but i am unable to send iDOC!
I tried to create a sample iDOC to test it but it doesn't work!
Exception in thread "main" java.lang.NoSuchMethodError: com.sap.conn.idoc.jco.SAPRepository$ConnectionProvider.execute(Lcom/sap/conn/jco/JCoFunction;Lcom/sap/conn/jco/rt/AbapRepository;)V
at com.sap.conn.idoc.jco.SAPRepository.queryRootSegmentMetaData40(SAPRepository.java:1204)
at com.sap.conn.idoc.jco.SAPRepository.queryRootSegmentMetaData(SAPRepository.java:1110)
at com.sap.conn.idoc.jco.SAPRepository.getRootSegmentMetaData(SAPRepository.java:909)
at com.sap.conn.idoc.rt.DefaultIDocDocument.<init>(DefaultIDocDocument.java:124)
at com.sap.conn.idoc.rt.DefaultIDocDocument.<init>(DefaultIDocDocument.java:61)
at com.sap.conn.idoc.jco.JCoIDocDocument.<init>(JCoIDocDocument.java:51)
at com.sap.conn.idoc.jco.JCoIDocRuntime.createIDocDocument(JCoIDocRuntime.java:133)
at com.sap.conn.idoc.jco.JCoIDocRuntime.createIDocDocument(JCoIDocRuntime.java:35)
at com.sap.conn.idoc.rt.DefaultIDocRuntime.createIDocDocument(DefaultIDocRuntime.java:175)
at com.sap.conn.idoc.rt.DefaultIDocRuntime.createIDocDocument(DefaultIDocRuntime.java:18)
at com.idoc.sender.IDocClientExample.main(IDocClientExample.java:49)
I even tried to send a sample iDOC XML but i am also facing another error, tried to change the XML many times but i am facing the same problem again an again!
com.sap.conn.idoc.IDocParseException: (7) IDOC_ERROR_PARSE_FAILURE: Invalid character encountered in XML input data source:
state=READING_XMLDECLARATION, charPosition=14, lineNumber=1, columnNumber=15, invalidChar=U+003D,
sourceSnippet=...#<?xml version="1.0" encoding="UTF-8"?><DEBMAS06><IDOC><EDI_DC40><DOCNUM>20120114120000</DOCNUM><IDO...
^
at com.sap.conn.idoc.rt.xml.DefaultIDocXMLParser.throwIDocParseException(DefaultIDocXMLParser.java:2223)
at com.sap.conn.idoc.rt.xml.DefaultIDocXMLParser.parseProlog(DefaultIDocXMLParser.java:1635)
at com.sap.conn.idoc.rt.xml.DefaultIDocXMLParser.parse(DefaultIDocXMLParser.java:320)
at com.sap.conn.idoc.rt.xml.DefaultIDocXMLProcessor.parse(DefaultIDocXMLProcessor.java:112)
at com.sap.conn.idoc.rt.xml.DefaultIDocXMLProcessor.parse(DefaultIDocXMLProcessor.java:54)
at com.sap.conn.idoc.rt.xml.DefaultIDocXMLProcessor.parse(DefaultIDocXMLProcessor.java:31)
at com.idoc.sender.IDocClientExample.main(IDocClientExample.java:57)
This is the code i am using to create the iDOC and send the iDOC XML:
package com.idoc.sender;
import com.sap.conn.idoc.*;
import com.sap.conn.idoc.jco.JCoIDoc;
import com.sap.conn.jco.JCoDestination;
import com.sap.conn.jco.JCoDestinationManager;
import java.io.BufferedReader;
import java.io.FileReader;
public class IDocClientExample {
public static void main(String[] args) {
try {
String iDocXML = null;
FileReader fileReader;
try {
fileReader = new FileReader("TestSalesOrder.xml");
BufferedReader br = new BufferedReader(fileReader);
StringBuffer sb = new StringBuffer();
String line;
while ((line = br.readLine()) != null) {
sb.append(line);
}
iDocXML = sb.toString();
br.close();
fileReader.close();
} catch (Exception ex) {
ex.printStackTrace();
}
// see provided configuration file xxxx.jcoDestination
JCoDestination destination = JCoDestinationManager.getDestination("xxxx");
IDocRepository iDocRepository = JCoIDoc.getIDocRepository(destination);
String tid = destination.createTID();
IDocFactory iDocFactory = JCoIDoc.getIDocFactory();
System.out.println(destination.getAttributes());
// a) create sample new idoc
IDocDocument doc = iDocFactory.createIDocDocument(iDocRepository, "SYSTAT01");
IDocSegment segment = doc.getRootSegment();
segment.addChild("E1MARAM");
JCoIDoc.send(doc, IDocFactory.IDOC_VERSION_DEFAULT, destination, tid);
// b) use existent xml file
IDocXMLProcessor processor = iDocFactory.getIDocXMLProcessor();
IDocDocumentList iDocList = processor.parse(iDocRepository, iDocXML);
JCoIDoc.send(iDocList, IDocFactory.IDOC_VERSION_DEFAULT, destination, tid);
destination.confirmTID(tid);
} catch (Exception e) {
e.printStackTrace();
}
System.out.print("program end");
}
}
// a) create sample new idoc
IDocDocument doc = iDocFactory.createIDocDocument(iDocRepository, "SYSTAT01");
IDocSegment segment = doc.getRootSegment();
segment.addChild("E1MARAM");
JCoIDoc.send(doc, IDocFactory.IDOC_VERSION_DEFAULT, destination, tid);
// b) use existent xml file
IDocXMLProcessor processor = iDocFactory.getIDocXMLProcessor();
IDocDocumentList iDocList = processor.parse(iDocRepository, iDocXML);
JCoIDoc.send(iDocList, IDocFactory.IDOC_VERSION_DEFAULT, destination, tid);
destination.confirmTID(tid);
} catch (Exception e) {
e.printStackTrace();
}
System.out.print("program end");
}
}
This is my connection file:
jco.client.lang=EN
jco.client.client=100
jco.client.passwd=xxxx
jco.client.user=xxxx
jco.client.sysnr=01
jco.client.ashost=xxxx
This is my xml file:
<?xml version="1.0" encoding="UTF-8"?>
<DEBMAS06>
<IDOC>
<EDI_DC40>
<DOCNUM>20120114120000</DOCNUM><IDOCTYP>DEBMAS06</IDOCTYP>
<MESTYP>DEBMAS</MESTYP>
<SNDPOR>HTTPDEMO</SNDPOR>
<SNDPRT>LS</SNDPRT>
<SNDPRN>HTTPDEMO</SNDPRN>
<RCVPOR>SAPxxx</RCVPOR>
<RCVPRT>LS</RCVPRT>
<RCVPRN>xxxCLNT100</RCVPRN>
</EDI_DC40>
<E1KNA1M segment="1">
<KUNNR>47</KUNNR>
<NAME1>Test Customer</NAME1>
<KTOKD>0004</KTOKD>
<SORTL>TEST</SORTL>
<ORT01>City</ORT01>
<LAND1>PL</LAND1>
<LZONE>A</LZONE>
<SPRAS>L</SPRAS>
<STRAS>Street</STRAS>
</E1KNA1M>
</IDOC>
</DEBMAS06>
I am using sapjco3-x86-64bit-3.0.5 and sapidoc-3.0.1!
Testing the creation of iDOC and sending IDOC XML is just for test but in our case, we have the iDOC ready!
My question is, how can i send iDOC directly from my disk to SAP via RFC? If i can't do so, how can i slove the error of creating iDOC or sending iDOC XML? My second question, once i am able to send iDOC, do i have to etablish a new SERVER RFC connection so i can receive iDOC from SAP?
** EDIT **
Now i ma able to send and receive IDoc properly. My problem is how i can get the IDoc as a Flat IDoc.
I can receive my IDoc as XML IDoc with this code:
package com.idoc.actif;
import com.sap.conn.idoc.IDocDocumentList;
import com.sap.conn.idoc.IDocXMLProcessor;
import com.sap.conn.idoc.jco.*;
import com.sap.conn.jco.server.*;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
public class IDocServerExample
{
public static void main(String[] a)
{
try
{
// see provided examples of configuration files xxxx.jcoServer and xxxx.jcoDestination
JCoIDocServer server = JCoIDoc.getServer("xxxx");
server.setIDocHandlerFactory(new MyIDocHandlerFactory());
server.setTIDHandler(new MyTidHandler());
MyThrowableListener listener = new MyThrowableListener();
server.addServerErrorListener(listener);
server.addServerExceptionListener(listener);
//server.setConnectionCount(1);
server.start();
}
catch (Exception e)
{
e.printStackTrace();
}
}
static class MyIDocHandler implements JCoIDocHandler
{
public void handleRequest(JCoServerContext serverCtx, IDocDocumentList idocList)
{
FileOutputStream fos=null;
OutputStreamWriter osw=null;
try
{
//receiving XML IDoc, how to get the IDoc as a Flat IDoc (SAP is sending the IDoc as Flat)???
IDocXMLProcessor xmlProcessor = JCoIDoc.getIDocFactory().getIDocXMLProcessor();
fos=new FileOutputStream(serverCtx.getTID());
osw=new OutputStreamWriter(fos, "UTF8");
xmlProcessor.render(idocList, osw, IDocXMLProcessor.RENDER_WITH_TABS_AND_CRLF);
osw.flush();
}
catch (Throwable thr)
{
thr.printStackTrace();
}
finally
{
try
{
if (osw!=null)
osw.close();
if (fos!=null)
fos.close();
}
catch (IOException e)
{
e.printStackTrace();
}
}
}
}
static class MyIDocHandlerFactory implements JCoIDocHandlerFactory
{
private JCoIDocHandler handler = new MyIDocHandler();
public JCoIDocHandler getIDocHandler(JCoIDocServerContext serverCtx)
{
return handler;
}
}
static class MyThrowableListener implements JCoServerErrorListener, JCoServerExceptionListener
{
public void serverErrorOccurred(JCoServer server, String connectionId, JCoServerContextInfo ctx, Error error)
{
System.out.println(">>> Error occured on " + server.getProgramID() + " connection " + connectionId);
error.printStackTrace();
}
public void serverExceptionOccurred(JCoServer server, String connectionId, JCoServerContextInfo ctx, Exception error)
{
System.out.println(">>> Error occured on " + server.getProgramID() + " connection " + connectionId);
error.printStackTrace();
}
}
static class MyTidHandler implements JCoServerTIDHandler
{
public boolean checkTID(JCoServerContext serverCtx, String tid)
{
System.out.println("checkTID called for TID="+tid);
return true;
}
public void confirmTID(JCoServerContext serverCtx, String tid)
{
System.out.println("confirmTID called for TID="+tid);
}
public void commit(JCoServerContext serverCtx, String tid)
{
System.out.println("commit called for TID="+tid);
}
public void rollback(JCoServerContext serverCtx, String tid)
{
System.out.print("rollback called for TID="+tid);
}
}
}
I guess that there is an incompatibility between the two SAP libraries that you use. I recommend to install the latest patch levels first. Currently this is JCo version 3.0.17 and the Java IDoc Library 3.0.12.
I only do not understand what you are doing with the StringBuffer here. If you would like to read IDoc-XML from a file, then the IDocXMLProcessor offers appropriate parse methods for this - the best would be
IDocXMLProcessor.parse(IDocRepository repository, InputStream xmlStream)
so that it also can take care of different file encodings as specified in the contained XML encoding attribute. If you choose a java.io.Reader or a String then you have to take care for this on your own (which you don't do in your example).
But in principle your code doesn't seem to be wrong at first sight.
In contrast to the IDoc-XML itself which is lacking the mandatory BEGIN="1" and SEGMENT="1" attributes for the <IDOC> and <EDI_DC40> tags.

Java Websocket closes immediately

I am trying to use TooTallNate's Java-Websocket to connect to OkCoin. I found this simple code example somewhere, but I can't get it to work. The connection is immediately closed and so the call mWs.send(...) throws a WebsocketNotConnectedException. I can't figure out why; so far I have found a number of similar questions, none of which have an answer.
import org.java_websocket.client.WebSocketClient;
import org.java_websocket.handshake.ServerHandshake;
import org.json.JSONObject;
import java.net.URI;
import java.net.URISyntaxException;
public class TestApp {
public static void main(String[] args) {
try {
URI uri = new URI("wss://real.okcoin.cn:10440/websocket/okcoinapi");
final WebSocketClient mWs = new WebSocketClient(uri) {
#Override
public void onMessage(String message) {
JSONObject obj = new JSONObject(message);
}
#Override
public void onOpen(ServerHandshake handshake) {
System.out.println("opened connection");
}
#Override
public void onClose(int code, String reason, boolean remote) {
System.out.println("closed connection");
}
#Override
public void onError(Exception ex) {
ex.printStackTrace();
}
};
mWs.connect();
JSONObject obj = new JSONObject();
obj.put("event", "addChannel");
obj.put("channel", "ok_btccny_ticker");
mWs.send(obj.toString());
} catch (URISyntaxException e) {
System.err.println("URI not formatted correctly");
}
}
}
Use mWs.connectBlocking() instead of mWs.connect() with this it will not close automatically.
See

Multiple messages on a Grizzly Websocket Connection

We are using Websockets from the Grizzly project and had expected that the implementation would allow multiple incoming messages over a connection to be processed at the same time. It appears that this is not the case or there is a configuration step that we have missed. To validate this I have created a modified echo test that delays in the onMessage after echoing the text. When a client sends multiple messages over the same connection the server always blocks until onMessage completes before processing a subsequent message. Is this the expected functionality?
The simplified server code is as follows:
package com.grorange.samples.echo;
import java.util.concurrent.atomic.AtomicBoolean;
import org.glassfish.grizzly.http.server.HttpServer;
import org.glassfish.grizzly.http.server.NetworkListener;
import org.glassfish.grizzly.websockets.DataFrame;
import org.glassfish.grizzly.websockets.WebSocket;
import org.glassfish.grizzly.websockets.WebSocketAddOn;
import org.glassfish.grizzly.websockets.WebSocketApplication;
import org.glassfish.grizzly.websockets.WebSocketEngine;
public class Echo extends WebSocketApplication {
private final AtomicBoolean inMessage = new AtomicBoolean(false);
#Override
public void onClose(WebSocket socket, DataFrame frame) {
super.onClose(socket, frame);
System.out.println("Disconnected!");
}
#Override
public void onConnect(WebSocket socket) {
System.out.println("Connected!");
}
#Override
public void onMessage(WebSocket socket, String text) {
System.out.println("Server: " + text);
socket.send(text);
if (this.inMessage.compareAndSet(false, true)) {
try {
Thread.sleep(10000);
} catch (Exception e) {}
this.inMessage.set(false);
}
}
#Override
public void onMessage(WebSocket socket, byte[] bytes) {
socket.send(bytes);
if (this.inMessage.compareAndSet(false, true)) {
try {
Thread.sleep(Long.MAX_VALUE);
} catch (Exception e) {}
this.inMessage.set(false);
}
}
public static void main(String[] args) throws Exception {
HttpServer server = HttpServer.createSimpleServer("http://0.0.0.0", 8083);
WebSocketAddOn addOn = new WebSocketAddOn();
addOn.setTimeoutInSeconds(60);
for (NetworkListener listener : server.getListeners()) {
listener.registerAddOn(addOn);
}
WebSocketEngine.getEngine().register("", "/Echo", new Echo());
server.start();
Thread.sleep(Long.MAX_VALUE);
}
}
The simplified client code is:
Yes, it's expected.
The way to go is to pass message processing, inside onMessage, to a different thread.

Categories