Como impedir que o xalan.jar que possui o META-INF \ services \ javax.xml.transform.TransformerFactory assuma o JDK 1.6 incorporado na implementação do Xalan?
Considere este código (baseado inteiramente no código de "introdução" do disco voador, seus direitos reservados):
package flyingsaucerpdf;
import java.io.File;
import java.io.FileOutputStream;
import java.io.OutputStream;
import org.xhtmlrenderer.pdf.ITextRenderer;
public class PDFMaker {
public static void main(String[] args) throws Exception {
new PDFMaker().go();
}
public void go() throws Exception {
String inputFile = "sample.html";
String url = new File(inputFile).toURI().toURL().toString();
String outputFile = "firstdoc.pdf";
OutputStream os = new FileOutputStream(outputFile);
ITextRenderer renderer = new ITextRenderer();
renderer.setDocument(url);
renderer.layout();
renderer.createPDF(os);
os.close();
}
}
Poucos fatos:
execução autônoma (chamada principal) com o JDK 1.6 ou 1.5 funciona perfeitamente (o PDF é geradMas quando carregado através de um URLClassLoader de um aplicativo Web existente, ele falha com este erro:Caused by: org.w3c.dom.DOMException: NAMESPACE_ERR: An attempt is made to create or change an object in a way which is incorrect with regard to namespaces. at org.apache.xerces.dom.AttrNSImpl.setName(Unknown Source) at org.apache.xerces.dom.AttrNSImpl.(Unknown Source) at org.apache.xerces.dom.CoreDocumentImpl.createAttributeNS(Unknown Source) at org.apache.xerces.dom.ElementImpl.setAttributeNS(Unknown Source) at org.apache.xml.utils.DOMBuilder.startElement(DOMBuilder.java:307) ... 19 more
Depois de procurar um tempo no lugar errado (por exemplo, criei um carregador de classe filho-primeiro / pai-última suspeitando de jarros xalan / xerces, mas ele ainda falha), finalmente reduzi a causa raiz:
Parece que o aplicativo da web que carrega meu código tem um @ anti xalan.jar, versão de especificação 1.2
Fiz um pequeno teste, executei o código acima como autônomo (que funcionava bem antes), mas desta vez adicionei o xalan.jar do aplicativo Web para o caminho da classe e do bingo, o mesmo erro que no cenário do aplicativo Web
Então, inspecionei o xalan.jar antigo e me perguntei: o que pode fazer com que a JVM carregue sua implementação xalan antiga em vez dos JDKs? afinal, meu carregador de primeira classe filho também é o último pai, por exemplo. sistema no meio, para dizer: pesquisando o carregador de classes do sistema antes do pai (para evitar carregar os frascos JDK pai substituídos, exatamente como neste caso do xalan.jar do pai, substituindo a implementação xalan do pai)
Então, algo chamou minha atenção - um arquivo em: xalan.jar / META-INF / services / named javax.xml.transform.TransformerFactory com este conteúdo:
org.apache.xalan.processor.TransformerFactoryImpl
Então eu imediatamente pressionei Ctrl+T no eclipse e procurou o nome completo qualificado ... apenas em xalan.jar!
Então procurei apenas "TransformerFactoryImpl", e é isso que o JDK tem:
com.sun.org.apache.xalan.internal.xsltc.trax.TransformerFactoryImpl
Fácil de ver a diferença
Então, se você ler até aqui, minha pergunta é:Como faço para o meu TransformerFactory usar a implementação do JDK e não a antiga do Xala (Não consigo remover esse jar do aplicativo Web do qual meu código será carregado)