[Resolvido] BinaryFileMarshaler - Stream closed

Bom dia,

Eu tenho um ESB que de tempo em tempo varre um email e verifica se existe algum XML na caixa de entrada.

Se tiver, ele vai salvar no computador. Eu leio ele 2 vezes, ai na segunda da um Stream Closed.

Como estou fazendo:

Passando a mensagem para frente - NFeMailForNfeProcPoller.java:

public void processFile(byte[] msg, String fileName) throws Exception {
	InputStream in = null;
	try {
		in = new BufferedInputStream(new ByteArrayInputStream(msg));
		InOnly exchange = getExchangeFactory().createInOnlyExchange();
		NormalizedMessage message = exchange.createMessage();
		exchange.setInMessage(message);
		fileMarshaler.readMessage(exchange, message, in, fileName);
		getDeliveryChannel().sendSync(exchange);
	} finally {
		if (in != null) {
			in.close();
		}
	}
}

Processando - [b]FileWriter.java/b

protected void process(MessageExchange exchange, NormalizedMessage message) throws Exception {

	String name = marshaler.getOutputName(exchange, message); //Aqui ele vai pro XMLFileNameExpression
	
	out = new BufferedOutputStream(new FileOutputStream(newFile));
			
	marshaler.writeMessage(exchange, message, out, newFile.getName()); //Aonde da o erro
}

Pegando nome do arquivo - [b]XMLFileNameExpression.java/b
Até aqui beleza, vem o Stream certinho…

public Object evaluate(MessageExchange exchange, NormalizedMessage message) throws MessagingException {

	ByteArrayOutputStream baos = new ByteArrayOutputStream();
	marshaller.writeMessage(exchange, message, baos, null);
	//... processo para pegar nome do arquivo

}

Pelo que li no site do apache, só pode ler uma vez o Stream, para ler mais de uma, tem que usar um

StringSource ou BytesSource, só não entendi muito bem como fazer, segue link:

https://cwiki.apache.org/confluence/display/SM/java.io.IOException+-+Stream+closed

Se faltou mais alguma info, só avisar, fico no aguardo, até mais.

Ah, ja ia esquecendo, ai o erro:

java.io.IOException: Stream closed at java.io.BufferedInputStream.getBufIfOpen(BufferedInputStream.java:145) at java.io.BufferedInputStream.read(BufferedInputStream.java:308) at java.io.FilterInputStream.read(FilterInputStream.java:90) at org.apache.servicemix.components.util.BinaryFileMarshaler.copyInputStream(BinaryFileMarshaler.java:108) at org.apache.servicemix.components.util.BinaryFileMarshaler.writeMessage(BinaryFileMarshaler.java:96) at br.inf.gati.componentes.file.FileWriter.process(FileWriter.java:165) at org.apache.servicemix.components.util.OutBinding.onMessageExchange(OutBinding.java:51) at org.apache.servicemix.jbi.messaging.DeliveryChannelImpl.processInBound(DeliveryChannelImpl.java:623) at org.apache.servicemix.jbi.nmr.flow.AbstractFlow.doRouting(AbstractFlow.java:172) at org.apache.servicemix.jbi.nmr.flow.seda.SedaFlow.doRouting(SedaFlow.java:168) at org.apache.servicemix.jbi.nmr.flow.seda.SedaQueue$1.run(SedaQueue.java:134) at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908) at java.lang.Thread.run(Thread.java:619)

Se souberem como pega o nome do arquivo usando MessageExchange e NormalizedMessage(sem o getOutPutName) ja da tambem…

Consegui resolver aqui, caso alguém tiver o mesmo problema da um toque ae.

podia colocar a solução? estou com o mesmo problema

Então, ele da isso porque só pode ler o stream uma vez por mensagem, e eu precisava ler mais de 1.

Antes de passar a mensagem para frente setei o content:

message.setContent( new StreamSource(new ByteArrayInputStream(msg)) );
marshaler.readMessage(exchange, message, in, fileName);

Depois da uma olhada nesses links ó:
http://servicemix.apache.org/dist/servicemix-3.0.1-incubating/site/servicemix-core/xref/org/apache/servicemix/jbi/jaxp/SourceTransformer.html

http://servicemix.396122.n5.nabble.com/Stream-closed-error-td410079.html#a410080

Usa o toStreamSourceFromDOM para pegar os bytes do arquivo, por exemplo:

Source source = message.getContent();
StreamSource ssource = null;
InputStream stream = null;

//Se o servicemix tiver como DEBUG, vem DOMSource
//Caso contrario StreamSource			
if (source instanceof DOMSource) {
    ssource = toStreamSourceFromDOM((DOMSource) source);
} else if ( source instanceof StreamSource ) {
    ssource = (StreamSource) source;
}
			
byte[] buffer = null;
if (ssource != null) {
    stream = ssource.getInputStream();
                
    buffer = new byte[stream.available()];
    stream.read(buffer);
}

Meio por cima, mas é isso ai…