ovirt-engine-sdk-java的使用過程中的錯誤整理

本篇記錄ovirt java sdk的使用前準備與使用中的一些坑。


0、參考文檔:

(1) Ovirt官方的Java-sdk文檔:https://www.ovirt.org/develop/release-management/features/infra/java-sdk/

(2) Javadoc.io的org.ovirt.engine.sdk 3.6.0.0文檔:https://javadoc.io/doc/org.ovirt.engine.sdk/ovirt-engine-sdk-java/3.6.0.0


1、下載ovirt java sdk的jar包

Maven地址:https://mvnrepository.com/artifact/org.ovirt.engine.sdk/ovirt-engine-sdk-java/3.6.0.0


2、下載org.ovirt.engine.sdk所需要的依賴包

在org.ovirt.enging.sdk下載頁面下方,有着一個“Compile Dependencies”表格,是sdk的依賴包。

根據表格中的信息下載相應的版本的jar包。

圖片.png

(1)commons-beanutils 1.8.3:https://mvnrepository.com/artifact/commons-beanutils/commons-beanutils/1.8.3

(2)log4j 1.2.17:https://mvnrepository.com/artifact/log4j/log4j/1.2.17

(3)httpclient 4.2:https://mvnrepository.com/artifact/org.apache.httpcomponents/httpclient/4.0


3、測試使用org.ovirt.engine.sdk

import org.ovirt.engine.sdk.Api;
import org.ovirt.engine.sdk.exceptions.ServerException;
import org.ovirt.engine.sdk.exceptions.UnsecuredConnectionAttemptError;

import java.io.IOException;
import java.security.KeyManagementException;
import java.util.List;

public class SdkTest {
    private static final String URL = "https://host/api/";
    private static final String USERNAME = "[email protected]";        // 普通用戶賬號
    private static final String PASSWORD = "123456";

    @SuppressWarnings("deprecation")
    public static void main(String[] args) throws ClientProtocolException, ServerException,  
                    UnsecuredConnectionAttemptError, IOException {

        Api api = new Api(URL, USERNAME, PASSWORD);
        
        List<VM> vm = api.getVMs().list();
        int len = vm.size();
        for (int i = 0; i < len; i ++) {
            System.out.printf("%s\n", vm.get(i).getName());
        }
        
        try {
            api.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
        
    }
    
}

* 注意:“ClientProtocolException”異常是Api類必須的,而且是在org.apache.http.client.ClientProtocolException(httpclient 4.2)中。


4、不停的ClassNotFoundException

(1)照理來說,只要將這些jar包放入buildpath中,就可以正常使用sdk了,但是實際的運行結果:

Exception in thread "main" java.lang.NoClassDefFoundError: org/apache/http/params/HttpParams
    at org.ovirt.engine.sdk.Api.<init>(Api.java:596)
    at org.ovirt.engine.sdk.Api.<init>(Api.java:109)
    at SdkTest.main(SdkTest.java:22)
Caused by: java.lang.ClassNotFoundException: org.apache.http.params.HttpParams
    at java.net.URLClassLoader.findClass(Unknown Source)
    at java.lang.ClassLoader.loadClass(Unknown Source)
    at sun.misc.Launcher$AppClassLoader.loadClass(Unknown Source)
    at java.lang.ClassLoader.loadClass(Unknown Source)
    ... 3 more

顯示缺少了org.apache.http.params.HttpParams,但是我並沒有用到這個東西!?

org.apache.http.params.HttpParams ----->>> httpcore-4.2.jar

httpcore 4.2的Maven地址:https://mvnrepository.com/artifact/org.apache.httpcomponents/httpcore/4.2


(2)加入了httpcore之後,還沒完:

Exception in thread "main" java.lang.NoClassDefFoundError: org/apache/commons/logging/LogFactory
    at org.apache.http.impl.conn.PoolingClientConnectionManager.<init>(PoolingClientConnectionManager.java:73)
    at org.apache.http.impl.conn.PoolingClientConnectionManager.<init>(PoolingClientConnectionManager.java:99)
    at org.apache.http.impl.conn.PoolingClientConnectionManager.<init>(PoolingClientConnectionManager.java:85)
    at org.ovirt.engine.sdk.web.ConnectionsPoolBuilder.createPoolingClientConnectionManager(ConnectionsPoolBuilder.java:314)
    at org.ovirt.engine.sdk.web.ConnectionsPoolBuilder.createDefaultHttpClient(ConnectionsPoolBuilder.java:257)
    at org.ovirt.engine.sdk.web.ConnectionsPoolBuilder.build(ConnectionsPoolBuilder.java:437)
    at org.ovirt.engine.sdk.Api.<init>(Api.java:607)
    at org.ovirt.engine.sdk.Api.<init>(Api.java:109)
    at SdkTest.main(SdkTest.java:22)
Caused by: java.lang.ClassNotFoundException: org.apache.commons.logging.LogFactory
    at java.net.URLClassLoader.findClass(Unknown Source)
    at java.lang.ClassLoader.loadClass(Unknown Source)
    at sun.misc.Launcher$AppClassLoader.loadClass(Unknown Source)
    at java.lang.ClassLoader.loadClass(Unknown Source)
    ... 9 more

這次缺的是org.apache.commons.logging.LogFactory。有種沒完沒了的感覺。

org.apache.commons.logging.LogFactory ----->>> commons-logging-1.2.jar

commons-logging 1.2的Maven地址:https://mvnrepository.com/artifact/commons-logging/commons-logging/1.2


(3)又加了jar包,再次運行程序:

Exception in thread "main" java.lang.NoClassDefFoundError: org/apache/commons/codec/binary/Base64
    at org.apache.http.impl.auth.BasicScheme.authenticate(BasicScheme.java:186)
    at org.apache.http.impl.auth.BasicScheme.authenticate(BasicScheme.java:158)
    at org.apache.http.client.protocol.RequestAuthenticationBase.authenticate(RequestAuthenticationBase.java:125)
    at org.apache.http.client.protocol.RequestAuthenticationBase.process(RequestAuthenticationBase.java:83)
    at org.apache.http.client.protocol.RequestTargetAuthentication.process(RequestTargetAuthentication.java:80)
    at org.apache.http.protocol.ImmutableHttpProcessor.process(ImmutableHttpProcessor.java:109)
    at org.apache.http.protocol.HttpRequestExecutor.preProcess(HttpRequestExecutor.java:176)
    at org.apache.http.impl.client.DefaultRequestDirector.execute(DefaultRequestDirector.java:516)
    at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:906)
    at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:805)
    at org.ovirt.engine.sdk.web.ConnectionsPool.execute(ConnectionsPool.java:97)
    at org.ovirt.engine.sdk.web.HttpProxy.execute(HttpProxy.java:114)
    at org.ovirt.engine.sdk.web.HttpProxyBroker.get(HttpProxyBroker.java:415)
    at org.ovirt.engine.sdk.web.HttpProxyBroker.get(HttpProxyBroker.java:394)
    at org.ovirt.engine.sdk.Api.getEntryPoint(Api.java:653)
    at org.ovirt.engine.sdk.Api.initResources(Api.java:665)
    at org.ovirt.engine.sdk.Api.<init>(Api.java:615)
    at org.ovirt.engine.sdk.Api.<init>(Api.java:109)
    at SdkTest.main(SdkTest.java:22)
Caused by: java.lang.ClassNotFoundException: org.apache.commons.codec.binary.Base64
    at java.net.URLClassLoader.findClass(Unknown Source)
    at java.lang.ClassLoader.loadClass(Unknown Source)
    at sun.misc.Launcher$AppClassLoader.loadClass(Unknown Source)
    at java.lang.ClassLoader.loadClass(Unknown Source)
    ... 19 more

是真的沒完沒了!?又缺了包!這次是org.apache.commons.codec.binary.Base64。到底是哪裏用到了這東西???

org.apache.commons.codec.binary.Base64 ----->>> commons-codec-1.10.jar

commons-codec 1.10的Maven地址:https://mvnrepository.com/artifact/commons-codec/commons-codec/1.10


5、創建Api代理過程中的錯誤

(1)執行上面的代碼,沒有ClassNotFoundException。但是出現了500服務器錯誤

Exception in thread "main"
code  : 500
reason: Internal Server Error

detail: <html><head><title>Error</title></head><body>Internal Server Error</body></html>
    at org.ovirt.engine.sdk.web.HttpProxy.execute(HttpProxy.java:120)
    at org.ovirt.engine.sdk.web.HttpProxyBroker.get(HttpProxyBroker.java:415)
    at org.ovirt.engine.sdk.web.HttpProxyBroker.get(HttpProxyBroker.java:394)
    at org.ovirt.engine.sdk.Api.getEntryPoint(Api.java:653)
    at org.ovirt.engine.sdk.Api.initResources(Api.java:665)
    at org.ovirt.engine.sdk.Api.<init>(Api.java:615)
    at org.ovirt.engine.sdk.Api.<init>(Api.java:109)
    at SdkTest.main(SdkTest.java:25)

不知道具體原因。代碼中使用的是普通賬號,但是該賬號和密碼在ovirt engine上能成功登錄。

後來使用管理員賬號登錄繞過了這個問題。


(2)管理員賬號登錄失敗,因爲證書驗證失敗

Exception in thread "main" javax.net.ssl.SSLPeerUnverifiedException: peer not authenticated
    at sun.security.ssl.SSLSessionImpl.getPeerCertificates(Unknown Source)
    at org.apache.http.conn.ssl.AbstractVerifier.verify(AbstractVerifier.java:128)
    at org.apache.http.conn.ssl.SSLSocketFactory.connectSocket(SSLSocketFactory.java:572)
    at org.apache.http.impl.conn.DefaultClientConnectionOperator.openConnection(DefaultClientConnectionOperator.java:180)
    at org.apache.http.impl.conn.ManagedClientConnectionImpl.open(ManagedClientConnectionImpl.java:294)
    at org.apache.http.impl.client.DefaultRequestDirector.tryConnect(DefaultRequestDirector.java:641)
    at org.apache.http.impl.client.DefaultRequestDirector.execute(DefaultRequestDirector.java:480)
    at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:906)
    at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:805)
    at org.ovirt.engine.sdk.web.ConnectionsPool.execute(ConnectionsPool.java:97)
    at org.ovirt.engine.sdk.web.HttpProxy.execute(HttpProxy.java:114)
    at org.ovirt.engine.sdk.web.HttpProxyBroker.get(HttpProxyBroker.java:415)


在這裏採用的解決方法是將ovirt engine的證書添加到jre的證書庫中。

首先將下載好的crt證書複製到jre的安裝目錄下的bin目錄中。

圖片.png

然後,在bin目錄下打開cmd,執行命令:

D:\Software\Java\jre1.8\bin>keytool -import -v -trustcacerts -alias svcloud -file pki-resource.cer -storepass changeit -keystore D:/Software/Java/jre1.8/lib/sec
urity/cacerts
所有者: CN=svcloud.casvip.com.46215, O=casvip.com, C=US
發佈者: CN=svcloud.casvip.com.46215, O=casvip.com, C=US
序列號: 1000
有效期爲 Wed Sep 12 10:43:25 CST 2018 至 Sun Sep 10 10:43:25 CST 2028
證書指紋:
         MD5:  35:B2:6F:79:15:29:7C:C3:39:D3:89:BC:1B:CA:08:38
         SHA1: 05:62:9C:41:42:92:2D:ED:07:86:FF:01:AD:4F:49:1E:1C:83:F3:B2
         SHA256: 99:37:BF:A9:CC:0B:FA:3C:C1:76:34:DA:71:22:02:2B:32:93:D4:D9:8B:
46:30:C6:B7:CC:CB:D9:08:B9:60:BD
簽名算法名稱: SHA256withRSA
主體公共密鑰算法: 2048 位 RSA 密鑰
版本: 3
。。。

是否信任此證書? [否]:  y
證書已添加到密鑰庫中
[正在存儲D:/Software/Java/jre1.8/lib/security/cacerts]

如果沒報錯,那麼證書添加完畢。


(3)404 Not Found

Exception in thread "main"
code  : 404
reason: Not Found

detail:
    at org.ovirt.engine.sdk.web.HttpProxy.execute(HttpProxy.java:120)
    at org.ovirt.engine.sdk.web.HttpProxyBroker.get(HttpProxyBroker.java:415)
    at org.ovirt.engine.sdk.common.CollectionDecorator.list(CollectionDecorator.java:180)
    at org.ovirt.engine.sdk.common.CollectionDecorator.list(CollectionDecorator.java:154)
    at org.ovirt.engine.sdk.decorators.VMs.list(VMs.java:75)
    at SdkTest.main(SdkTest.java:27)

把URL中的api最後的“/”去掉即可。並且URL一定是以“/api”結尾的。


(4)端口錯誤

Exception in thread "main" java.lang.IllegalArgumentException: Port is invalid: -1
    at org.apache.http.conn.scheme.Scheme.<init>(Scheme.java:90)
    at org.ovirt.engine.sdk.web.ConnectionsPoolBuilder.createSchemeRegistry(ConnectionsPoolBuilder.java:381)
    at org.ovirt.engine.sdk.web.ConnectionsPoolBuilder.createPoolingClientConnectionManager(ConnectionsPoolBuilder.java:312)
    at org.ovirt.engine.sdk.web.ConnectionsPoolBuilder.createDefaultHttpClient(ConnectionsPoolBuilder.java:257)
    at org.ovirt.engine.sdk.web.ConnectionsPoolBuilder.build(ConnectionsPoolBuilder.java:437)
    at org.ovirt.engine.sdk.Api.<init>(Api.java:607)
    at org.ovirt.engine.sdk.Api.<init>(Api.java:109)
    at SdkTest.main(SdkTest.java:24)

在URL中的host後面添加端口即可。如果使用的端口是8080,那麼就是https://host:8080/api


6、org.ovirt.engine.sdk所需要的所有jar包

D:\Desktop\org.ovirt.engine及其依賴>dir
 驅動器 D 中的卷是 軟件
 卷的序列號是 DA18-EBFA

 D:\Desktop\org.ovirt.engine及其依賴 的目錄

2018-10-29  15:25    <DIR>          .
2018-10-29  15:25    <DIR>          ..
2018-10-29  11:25           232,019 commons-beanutils-1.8.3.jar
2018-10-29  14:55           284,184 commons-codec-1.10.jar
2018-10-29  14:05            61,829 commons-logging-1.2.jar
2018-10-29  11:25           424,648 httpclient-4.2.jar
2018-10-29  11:38           223,282 httpcore-4.2.jar
2018-10-29  11:21           489,884 log4j-1.2.17.jar
2018-10-29  10:19         1,085,280 ovirt-engine-sdk-java-3.6.0.0.jar
               7 個文件      2,801,126 字節
               2 個目錄 63,892,709,376 可用字節


在最後的時候,才發現,原來後面缺少的jar包都是sdk的依賴包的依賴包。有點繞口,看圖就知道了。

(1)commons-beanutils的依賴包

圖片.png

(2)log4j的依賴包

圖片.png

(3)httpclient的依賴包

圖片.png

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章