Sending iDOC from Java to SAP - java

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.

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("=", ":"));

calling a java class method in another class

Hi I have below Java Class for Sending Fax from Java
package oracle.apps.print;
import com.softlinx.replixfax.*;
import javax.xml.ws.*;
import org.apache.commons.codec.binary.Base64;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.nio.file.Path;
import java.io.File;
public class Fax {
public void SendFax(String Filepath, String faxno) {
try {
ReplixFaxService service = new ReplixFaxService();
ReplixFaxPort port = service.getReplixFaxPort();
((BindingProvider)port).getRequestContext().put(BindingProvider.USERNAME_PROPERTY, "admin");
// ((BindingProvider) port).getRequestContext().put(BindingProvider.ENDPOINT_ADDRESS_PROPERTY,"https://api.rpxfax.com/softlinx/replixfax/wsapi");
((BindingProvider)port).getRequestContext().put(BindingProvider.ENDPOINT_ADDRESS_PROPERTY,
"https://api.rpxtest.com:9999/softlinx/replixfax/wsapi");
Authentication auth = new Authentication();
auth.setLogin("user");
String password = "pwd";
auth.setPassword(org.apache.commons.codec.binary.Base64.encodeBase64String(password.getBytes()));
auth.setRealm("MTBC");
auth.setPasswordSecurity("base64");
SendFaxInput sendFaxInput = new SendFaxInput();
sendFaxInput.setAuthentication(auth);
FaxRecipient recipient = new FaxRecipient();
recipient.setFaxNumber(faxno.toString());
Attachment attachment = new Attachment();
File f = new File(Filepath.toString());
attachment.setFileName(f.getName());
Path path = Paths.get(Filepath.toString());
byte[] data = Files.readAllBytes(path);
attachment.setAttachmentContent(data);
sendFaxInput.getFaxRecipient().add(recipient);
sendFaxInput.getAttachment().add(attachment);
SendFaxOutput result = port.sendFax(sendFaxInput);
System.out.println("Status Code= " + result.getRequestStatus().getStatusCode());
if (result.getFaxInfo() != null) {
System.out.println("Fax ID = " + result.getFaxInfo().get(0).getFaxId());
}
} catch (Exception ex) {
System.out.println("Exception: " + ex.getMessage());
}
}
}
I am compiling this class like this
javac -cp .;./commons-codec-1.10.jar Fax.java
However Compiling of both classes is fine no error at compile time
when i call the method Fax in another class (XXEmail) like this
package oracle.apps.print;
public class XXEmail implements JavaConcurrentProgram {
public static void main(String[] args) {
try {
Fax mtbcfax = new Fax();
mtbcfax.SendFax("E:\\csv_svb\\3010218.pdf", "173224xxxx");
out.writeln("Fax Sent Successfully");
} catch (Exception i) {
log.writeln("Error while Sending Fax " + i.getMessage(), LogFile.STATEMENT);
} finally {
log.writeln("Error while Sending Fax ");
}
}
}
It always goes to Finally block with out showing any error
How can i call this method so it should return with success code or exception
Try to:
Comment all lines in the SendFax function and add only a log:
public void SendFax(String Filepath, String faxno) {
out.writeln("No problem here");
}
Now start the program and see if the function is correctly called or not.
If It is correctly called, so probably the arguments you send are wrong.

JAX-RS ChunkedOutput and ChunkedInput with Wildfly

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();
}

read JSON from url on JavaFX controller does not update when JSON updated

I try to create java program that read JSON from this url, the url contain JSON array that updated every 20 seconds here is my java program that listen to the url and print the last JSON object from the JSON file:
ListenTojson.java
package com.company;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import java.io.*;
import java.net.URL;
import java.nio.charset.Charset;
class ListenToJson implements Runnable {
public void run() {
long tenSeconds = 10*1000L;
while(true) {
try {
JSONArray json = readJsonFromUrl("http://frozen-brook-16337.herokuapp.com/history.json");
JSONObject jo=json.getJSONObject(json.length()-1);
System.out.println(jo.get("data"));
Thread.sleep(tenSeconds);
} catch (InterruptedException e) {
e.printStackTrace();
} catch (JSONException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
private static String readAll(Reader rd) throws IOException {
StringBuilder sb = new StringBuilder();
int cp;
while ((cp = rd.read()) != -1) {
sb.append((char) cp);
}
return sb.toString();
}
public static JSONArray readJsonFromUrl(String url) throws IOException, JSONException {
InputStream is = new URL(url).openStream();
try {
BufferedReader rd = new BufferedReader(new InputStreamReader(is, Charset.forName("UTF-8")));
String jsonText = readAll(rd);
JSONArray jsonArray = new JSONArray(jsonText);
return jsonArray;
} finally {
is.close();
}
}
}
Main.java
package com.company;
public class Main {
public static void main(String[] args){
(new Thread(new ListenToJson())).start();
}
}
The code run as I expected. The JSON file contains coordinate that keep updated every 10 seconds. I need to create map application that read the coordinate from the JSON and then show it on the map as marker, I use JavaFx library to create the map application, when I add the code above (ListenToJson.java) the program behave differently when I use JavaFX library it does not read the latest JSON file.
here is the code
public class Controller{
//some code
(new Thread(new ListenToJson())).start();
//some code
}
Controller.java
The full class that I try to update the UI using the ListenToJson() function is here https://github.com/kikirizki/mapapp/blob/master/src/main/java/com/delameta/vesselmap/Controller.java the line 526, thanks
whats wrong with my code, why the ListenToJson() function read the outdated JSON file ?
I found the solution myself, the problem is the mapjfx library (I use in the code) use cache to cache the map tile and then it cause to cache the JSON file too. The solution is simply disable the cache mechanism, just diable it at line 350, change
offlineCache.setActive(true);
to be
offlineCache.setActive(false);

java write class to file

This is for a homework I'm doing on my walk learning java.
I'm writing a program and it is all working as expected except the read/write to file.
I have one class named Medico that holds only one string (typeOfMedico) and one int (valorFacturado). Medico is a sub class of Pessoa. Pessoa holds data like name and address. public class Medico extends Pessoa implements Serializable is the main function on Medicoclass.
On my main class, named Clinica, I ask for user input and at the end of I create a new Medico that its added to an Arraylist named medico.
For reading and writing to file I've created this class:
package clinica;
import java.io.EOFException;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
public class FicheiroObjectos {
private ObjectInputStream iS;
private ObjectOutputStream oS;
public void abreLeitura(String nomeDoFicheiro) throws IOException {
iS = new ObjectInputStream(new FileInputStream(nomeDoFicheiro));
}
public void abreEscrita(String nomeDoFicheiro) throws IOException {
oS = new ObjectOutputStream(new FileOutputStream(nomeDoFicheiro));
}
public Object leObjecto() throws IOException, ClassNotFoundException {
return iS.readObject();
}
public void escreveObjecto(Object o) throws IOException {
oS.writeObject(o);
}
public void fechaLeitura() throws IOException {
iS.close();
}
public void fechaEscrita() throws IOException {
oS.close();
}
public void leFicheiroMedicos() {
Medico medicos;
while (true) {
try {
medicos = (Medico) this.leObjecto();
Clinica.medicos.add(medicos);
} catch (EOFException eof) {
break;
} catch (ClassNotFoundException cnf) {
System.out.print("\nClassNotFoundException!\nO programa vai terminar\n");
System.exit(-1);
} catch (IOException ioe) {
System.out.print("\nErro ao ler o ficheiro!\nO programa vai terminar\n");
System.exit(-1);
}
}
}
public void escreveFicheiroMedicos() {
try {
for (Medico medicos: Clinica.medicos) {
this.escreveObjecto(medicos);
}
} catch (IOException e) {
System.out.print("\nErro ao escrever no ficheiro!\nO programa vai terminar\n");
System.exit(-1);
}
}
}
On my main class I've created this two functions:
public static void insereDadosExistentes() {
try {
FicheiroObjectos file = new FicheiroObjectos();
file.abreLeitura("Medicos.dat");
file.leFicheiroMedicos();
file.fechaLeitura();
} catch (IOException ioe) {
}
}
public static void gravarMedicos() {
try {
FicheiroObjectos file = new FicheiroObjectos();
file.abreEscrita("Medicos.dat");
file.escreveFicheiroMedicos();
file.fechaEscrita();
} catch (IOException e) {
System.out.print("\nErro ao escrever no ficheiro!\nO programa vai terminar\n");
System.exit(-1);
}
}
}
Then added insereDadosExistentes() at the beginning of my mainfunction and added gravarMedicos() just after adding a Medico to my medicos arraylist.
When I run my program (On the first run, file Medicos.dat, does not exist) and create a Medico, Medico is added to my arraylist and the file Medicos.dat is created. Then I stop the program and on the next run, which now haves a Medicos.dat file, I get the error:
Erro ao ler o ficheiro!
O programa vai terminar
The problem is in writing the file or reading the file?
I know the error is given when reading the file but it could be because the writhing to file is not properly executed.
If I try to open Medicos.dat I can see some characters but nothing related with the info I input so I don't even know if the file writing is ok.
Remember that all besides file handling is working as expected.
Can you point me In some directions?
favolas
Make sure that you explicitly close the ObjectOutputStream so that all the data is written.
Your problem is an IOException. However, the backtrace will tell you what's going on: trouble opening, reading, what? you can call printStackTrace(), but better you can use a debugging and just look at the stack trace.
If you catch an exception dont just write something to system.out but print the stacktrace this will usually give you a clue whats wrong
try {
FicheiroObjectos file = new FicheiroObjectos();
file.abreEscrita("Medicos.dat");
file.escreveFicheiroMedicos();
file.fechaEscrita();
} catch (IOException e) {
e.printStackTrace();
}
Q: Are you trying to read and write DATA, or are you trying to serialize and deserialize OBJECTS?
I think all you need to do is open and write to a simple text file:
For example:
http://www.exampledepot.com/egs/java.io/AppendToFile.html
import java.io.*;
public class TestFile
{
public static void main (String[] args)
{
// Test "append"
// SOURCE: http://www.exampledepot.com/egs/java.io/AppendToFile.html
try {
BufferedWriter out =
new BufferedWriter(
new FileWriter("myfile.txt", true));
out.write("testing: a b c\n");
out.write("testing: d e f\n");
out.close();
}
catch (IOException e) {
}
}
}
Sample output:
testing: a b c
testing: d e f
I don't know Java's serialization stuff at all, but this seems "too easy":
public void escreveObjecto(Object o) throws IOException {
oS.writeObject(o);
}
How is the object output stream supposed to know what portions of your object needs to be written to disk? Could be that your object contains nothing but computed values that shouldn't be stored. Could be that your object's data needs to be stored completely. Perhaps references to String objects should just be dropped... or perhaps those Strings should be written to disk.
There must be more to using the ObjectStream stuff than you're showing here -- and paulsm4's answer shows how writing your own content by hand isn't too bad. Should you be taking that approach instead? Does your class have a defined storage format that you must adhere to?

Categories