Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/svn/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Xml JAXB解组在输入流末尾的SAXParseException中结束_Xml_Svn_Xsd_Jaxb_Jsch - Fatal编程技术网

Xml JAXB解组在输入流末尾的SAXParseException中结束

Xml JAXB解组在输入流末尾的SAXParseException中结束,xml,svn,xsd,jaxb,jsch,Xml,Svn,Xsd,Jaxb,Jsch,我正在开发一个简短的应用程序,它应该从SVN存储库中的项目中读取一些元数据 SVN本身提供了一些命令行工具。其中一个工具是“SVN列表”。如果给定选项--xml,list命令可以传递xml。因此,如果您想总结或积累一些数据,可以使用linux(在本例中是OS)命令。但是,当您想要拥有不同的数据和存储库变得更大时,它就会变得太复杂和缓慢(在我看来) 我的解决方案使用JSch为给定的存储库路径建立连接并检索xml。下一步是使用JAXB将xml解组到类中,然后(理论上)遍历对象 所以我有 -xml

我正在开发一个简短的应用程序,它应该从SVN存储库中的项目中读取一些元数据

SVN本身提供了一些命令行工具。其中一个工具是“SVN列表”。如果给定选项--xml,list命令可以传递xml。因此,如果您想总结或积累一些数据,可以使用linux(在本例中是OS)命令。但是,当您想要拥有不同的数据和存储库变得更大时,它就会变得太复杂和缓慢(在我看来)

我的解决方案使用JSch为给定的存储库路径建立连接并检索xml。下一步是使用JAXB将xml解组到类中,然后(理论上)遍历对象

所以我有 -xml

 <?xml version="1.0"?>
    <lists>
    <list
       path="<URL>/svn/Repository/<anyProject>/trunk">
    </list>
    </lists>
我已经在这里和其他地方做了很多研究,但从来没有发现关于流结束的东西(我不是天真的-我知道现在流或数组中有流结束)

更多详情: 我从JSch接收一个输入流,并将其存储在ByteBuffer中:

public ByteBuffer sendCommandForInputStream(String command) {
        try {
            Channel channel = sesConnection.openChannel("exec");
            ((ChannelExec) channel).setCommand(command);
            InputStream commandOutput = channel.getInputStream();
            channel.connect();

            byte[] bytes = IOUtils.toByteArray(commandOutput);

            ByteBuffer result = ByteBuffer.wrap(bytes);
            channel.disconnect();
            return result;
        }
        catch (IOException ioX) {
            logWarning(ioX.getMessage());
            return null;
        }
        catch (JSchException jschX) {
            logWarning(jschX.getMessage());
            return null;
        }
    }
我必须使用缓冲区,因为如果我在打开连接后关闭连接,我不是100%,结果是完整的

unmarshal方法也接受InputStream,因此我必须将其“转换”回来。也许这个bug就在这里:

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.nio.ByteBuffer;

import javax.xml.XMLConstants;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Unmarshaller;
import javax.xml.transform.stream.StreamSource;
import javax.xml.validation.Schema;
import javax.xml.validation.SchemaFactory;

import org.xml.sax.SAXException;

public class RepoJaxbUtil {
    public static <T> T unmarshal(ByteBuffer xml, Class<T> clss) throws JAXBException, SAXException, UnsupportedEncodingException {
        SchemaFactory schemaFactory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
        Schema schema = schemaFactory.newSchema(new File("subversionRepo.xsd"));
        JAXBContext jaxbContext = JAXBContext.newInstance(clss.getPackage().getName());
        InputStream xmlS = newInputStream(xml);
        return unmarshal(jaxbContext, schema, xmlS, clss);
    }

    public static <T> T unmarshal(JAXBContext jaxbContext, Schema schema, InputStream xml, Class<T> clss) throws JAXBException, UnsupportedEncodingException {
        Unmarshaller unmarshaller = jaxbContext.createUnmarshaller();
        unmarshaller.setSchema(schema);
        StreamSource xmlSource = new StreamSource(xml);
        return clss.cast(unmarshaller.unmarshal(xmlSource));
    }

    public static InputStream newInputStream(final ByteBuffer buf) {
        return new InputStream() {
            public synchronized int read() throws IOException {
                if (!buf.hasRemaining()) {
                    return -1;
                }
                return buf.get();
            }

            public synchronized int read(byte[] bytes, int off, int len) throws IOException {
                // Read only what's left
                len = Math.min(len, buf.remaining());
                buf.get(bytes, off, len);
                return len;
            }
        };
    }
  }
/*(The transfer to a InputSource does not work => just the line from 6 to 7 and the other way around)*/
导入java.io.File;
导入java.io.IOException;
导入java.io.InputStream;
导入java.io.UnsupportedEncodingException;
导入java.nio.ByteBuffer;
导入javax.xml.xmlstants;
导入javax.xml.bind.JAXBContext;
导入javax.xml.bind.JAXBException;
导入javax.xml.bind.Unmarshaller;
导入javax.xml.transform.stream.StreamSource;
导入javax.xml.validation.Schema;
导入javax.xml.validation.SchemaFactory;
导入org.xml.sax.SAXException;
公共类RepoJaxbUtil{
公共静态T unmarshal(ByteBuffer xml,类clss)抛出JAXBEException、SAXException、UnsupportedEncodingException{
SchemaFactory SchemaFactory=SchemaFactory.newInstance(xmlstants.W3C\u XML\u SCHEMA\u NS\u URI);
Schema Schema=schemaFactory.newSchema(新文件(“subversionRepo.xsd”);
JAXBContext JAXBContext=JAXBContext.newInstance(clss.getPackage().getName());
InputStream xmlS=newInputStream(xml);
返回unmarshal(jaxbContext、schema、xmlS、cls);
}
公共静态T unmarshal(JAXBContext、JAXBContext、模式模式、InputStream xml、类cls)抛出jaxbeexception、UnsupportedEncodingException{
Unmarshaller Unmarshaller=jaxbContext.createUnmarshaller();
解组器。设置模式(模式);
StreamSource xmlSource=新的StreamSource(xml);
返回clss.cast(unmarshaller.unmarshal(xmlSource));
}
公共静态输入流newInputStream(最终ByteBuffer buf){
返回新的InputStream(){
public synchronized int read()引发IOException{
如果(!buf.haslaining()){
返回-1;
}
返回buf.get();
}
公共同步整数读取(字节[]字节,整数关闭,整数长度)引发IOException{
//只读剩下的内容
len=Math.min(len,buf.remaining());
buf.get(字节、off、len);
回程透镜;
}
};
}
}
/*(到InputSource的传输不起作用=>仅从6到7的行,反之亦然)*/

有人知道如何解决这个问题吗

所以在@lexicore(谢谢)声明给定的xml无效后,我自己找到了一个解决方案

xml本身是正确的,但是JSch处理程序类中的处理是不正确的。在RepoJaxbUtil类中的方法“newInputStream(final ByteBuffer buf)”中存在的问题。在导致无效xml内容的inputstream的最后一个字符后面,我设置了“-1”

我在JSch SSH处理程序中更改了返回类型和名称:

     public StringBuffer sendCommandForBuffer(String command) {

        StringBuffer outputBuffer = new StringBuffer();
        try {
            Channel channel = sesConnection.openChannel("exec");
            ((ChannelExec) channel).setCommand(command);
            InputStream commandOutput = channel.getInputStream();
            channel.connect();
            int readByte = commandOutput.read();

            while (readByte != 0xffffffff) {
                outputBuffer.append((char) readByte);                
                readByte = commandOutput.read();
            }

            return outputBuffer;
        }
        catch (IOException ioX) {
            logWarning(ioX.getMessage());
            return null;
        }
        catch (JSchException jschX) {
            logWarning(jschX.getMessage());
            return null;
        }
    }
另一方面,为了简单起见,我检查了RepoJaxbUtil类并“消除”了threadsafety(我很确定这不会导致问题):

另一个简短而重要的建议可能是将业务逻辑类从JAXBElement调用并强制转换为目标对象类型(这可能不太好,但对我来说是这样的):


您的XML显然无效。很难说问题到底出在哪里,因为有很多步骤可能会出错。您只需要仔细调试它。
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.nio.ByteBuffer;

import javax.xml.XMLConstants;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Unmarshaller;
import javax.xml.transform.stream.StreamSource;
import javax.xml.validation.Schema;
import javax.xml.validation.SchemaFactory;

import org.xml.sax.SAXException;

public class RepoJaxbUtil {
    public static <T> T unmarshal(ByteBuffer xml, Class<T> clss) throws JAXBException, SAXException, UnsupportedEncodingException {
        SchemaFactory schemaFactory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
        Schema schema = schemaFactory.newSchema(new File("subversionRepo.xsd"));
        JAXBContext jaxbContext = JAXBContext.newInstance(clss.getPackage().getName());
        InputStream xmlS = newInputStream(xml);
        return unmarshal(jaxbContext, schema, xmlS, clss);
    }

    public static <T> T unmarshal(JAXBContext jaxbContext, Schema schema, InputStream xml, Class<T> clss) throws JAXBException, UnsupportedEncodingException {
        Unmarshaller unmarshaller = jaxbContext.createUnmarshaller();
        unmarshaller.setSchema(schema);
        StreamSource xmlSource = new StreamSource(xml);
        return clss.cast(unmarshaller.unmarshal(xmlSource));
    }

    public static InputStream newInputStream(final ByteBuffer buf) {
        return new InputStream() {
            public synchronized int read() throws IOException {
                if (!buf.hasRemaining()) {
                    return -1;
                }
                return buf.get();
            }

            public synchronized int read(byte[] bytes, int off, int len) throws IOException {
                // Read only what's left
                len = Math.min(len, buf.remaining());
                buf.get(bytes, off, len);
                return len;
            }
        };
    }
  }
/*(The transfer to a InputSource does not work => just the line from 6 to 7 and the other way around)*/
     public StringBuffer sendCommandForBuffer(String command) {

        StringBuffer outputBuffer = new StringBuffer();
        try {
            Channel channel = sesConnection.openChannel("exec");
            ((ChannelExec) channel).setCommand(command);
            InputStream commandOutput = channel.getInputStream();
            channel.connect();
            int readByte = commandOutput.read();

            while (readByte != 0xffffffff) {
                outputBuffer.append((char) readByte);                
                readByte = commandOutput.read();
            }

            return outputBuffer;
        }
        catch (IOException ioX) {
            logWarning(ioX.getMessage());
            return null;
        }
        catch (JSchException jschX) {
            logWarning(jschX.getMessage());
            return null;
        }
    }
public class RepoJaxbUtil {

     public static Object unmarshal(StringBuffer xml, Class clss) throws JAXBException, SAXException, UnsupportedEncodingException {
        SchemaFactory schemaFactory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
        Schema schema = schemaFactory.newSchema(new File("subversionRepo.xsd"));
        JAXBContext jaxbContext = JAXBContext.newInstance(clss.getPackage().getName());
        Unmarshaller unmarshaller = jaxbContext.createUnmarshaller();
        unmarshaller.setSchema(schema);
        StreamSource source = new StreamSource(new StringReader(xml.toString()));
        return unmarshaller.unmarshal(source);
    }
}
xmlReturn = instance.sendCommandForBuffer(cmd);
                ListsType repoLists;

                try {
                    JAXBElement lt = (JAXBElement) RepoJaxbUtil.unmarshal(xmlReturn, ListsType.class);
                    LOG.info(lt.toString());
                    repoLists = (ListsType) lt.getValue();

                    // any other business logic here

                    LOG.info("entryCount: " + repoLists.getList().getEntryType().size());
                }
                catch (JAXBException e) {
                    LOG.warn("JAXBException occured on project [" + project + "]");
                    e.printStackTrace();
                }
                catch (SAXException e) {
                    LOG.warn("SAXException occured on project [" + project + "]");
                    e.printStackTrace();
                }
                catch (UnsupportedEncodingException e) {
                    LOG.warn("UnsupportedEncodingException occured on project [" + project + "]");
                    e.printStackTrace();
                }