2016-09-14 90 views
2

我試圖運行一個在本地工作的Spark作業。它使用Google Storage。我得到這個錯誤:NoSuchMethodError StorageObject.getTimeCreated在Dataproc中運行作業

Exception in thread "main" java.lang.NoSuchMethodError: com.google.api.services.storage.model.StorageObject.getTimeCreated()Lcom/google/api/client/util/DateTime; 
    at com.google.cloud.storage.BlobInfo.fromPb(BlobInfo.java:798) 
    at com.google.cloud.storage.Blob.fromPb(Blob.java:641) 
    at com.google.cloud.storage.StorageImpl.create(StorageImpl.java:139) 
    at com.google.cloud.storage.StorageImpl.create(StorageImpl.java:132) 
... 

Dataproc的工作就是使用gcloud-java-storage-0.2.8.jar,我都試過google-api-services-storage-v1-rev62-1.21.0.jargoogle-api-services-storage-v1-rev83-1.22.0.jar沒有成功,即使該方法被定義。它看起來沒有使用正確版本的google-api-services-storage,但我不知道除了上傳和指定jar之外我還能做什麼。

有什麼我失蹤?

回答

3

看起來好像問題在於Dataproc內置的GCS連接器目前版本爲compiles against an oldergoogle-api-services-storage-v1版本。 com.google.api.services.storage.model.StorageObject.getTimeCreated()方法僅在更高版本中添加,所以當舊版本在類路徑上獲勝時,會出現該錯誤。驗證完全向後兼容性後,我們可能會在不久的將來版本中更新該版本。與此同時,您可以嘗試使用您自己的fatjar中的陰影插件重新打包com.google.api.services.storage.*程序包,就像GCS連接器repackages com.google.common.*一樣,以避免與帶有自己的Guava版本的用戶發生類路徑衝突,或者您可以嘗試重新編譯GCS連接器自己和它換到使用一個初始化動作的Dataproc集羣(基本上可以複製/粘貼的一切逐字這裏,除非你需要提供一個GCS桶的第一行):

export GCS_BUCKET=[SOME BUCKET YOU OWN HERE WITHOUT gs:// PREFIX] 


# Clone the code, update the dependency, build it 
git clone https://github.com/GoogleCloudPlatform/bigdata-interop.git 
cd bigdata-interop 
sed -i "s/v1-rev35/v1-rev83/" pom.xml 
mvn -P hadoop2 package 


# Upload the new GCS connector to GCS 
gsutil cp gcs/target/gcs-connector-1.5.3-hadoop2-SNAPSHOT-shaded.jar gs://${GCS_BUCKET}/gcs-connector-1.5.3-hadoop2-SNAPSHOT-shaded.jar 


# Create a quick init action 
cat <<EOF> install_new_gcs.sh 

#!/bin/bash 
rm /usr/lib/hadoop/lib/gcs-connector-*.jar 
gsutil cp gs://${GCS_BUCKET}/gcs-connector-1.5.3-hadoop2-SNAPSHOT-shaded.jar \ 
    /usr/lib/hadoop/lib/ 
chmod 644 /usr/lib/hadoop/lib/gcs-connector-*.jar 

EOF 
gsutil cp install_new_gcs.sh gs://${GCS_BUCKET}/install_new_gcs.sh 


# Create your dataproc cluster 
gcloud dataproc clusters create ${USER}-new-connector \ 
    --initialization-actions gs://${GCS_BUCKET}/install_new_gcs.sh 

順便說一句,因爲這裏的根本原因是自動安裝的Hadoop GCS連接器與您自己的GCS庫之間的衝突,您可能會遇到螞蟻考慮在你的代碼中使用Hadoop FileSystem接口;在Dataproc中,將配置此選項,以便在通過Path的任何地方,可以使用形式爲gs://bucket/foo/bar的路徑,並且它會自動加載GCS連接器庫以便正常工作。你的代碼看起來是這樣的:

import org.apache.hadoop.fs.Path; 
import org.apache.hadoop.fs.FileSystem; 
import org.apache.hadoop.conf.Configuration; 

... 
Path foo = new Path("gs://my-bucket/my-data.txt"); 
InputStream is = foo.getFileSystem(new Configuration()).open(foo); 
... 
+0

首先,謝謝你非常,丹尼斯。我嘗試了你的instuctions來重新編譯和交換,當我嘗試運行一個工作時,我得到這個錯誤:'===========雲Dataproc代理錯誤=========== 顯示java.lang.NullPointerException \t在com.google.api.client.util.SecurityUtils.loadKeyStore(SecurityUtils.java:84) \t在com.google.api.client.googleapis.GoogleUtils.getCertificateTrustStore(GoogleUtils.java:76 ) \t at com.google.api.client.googleapis.javanet.GoogleNetHttpTransport.newTrustedTransport(GoogleNetHttpTransport.java:55)'。任何線索? – juanignaciosl

+0

我也在嘗試使用Hadoop FS,但作業失敗:'ExitCodeException exitCode = 52:at org.apache.hadoop.util.Shell.runCommand(Shell.java:545)...'。我仍然試圖調試到Hadoop本身,但它似乎相關:如果我運行我的作業替換寫一個簡單的標準輸出消息它的作品。 – juanignaciosl

+0

使用'Path foo = new Path(「gs://my-bucket/my-data.txt」);'style終於爲我工作了,謝謝! – juanignaciosl

0

我遇到了1.0版本的Dataproc相同的問題。我解決它通過添加在我的羣集初始化操作如下:此外

#!/bin/bash 

rm /usr/lib/hadoop/lib/bigquery-connector-0.10.1-hadoop2.jar 
rm /usr/lib/hadoop/lib/gcs-connector-1.6.0-hadoop2.jar 

rm /usr/lib/hadoop/lib/guava-11.0.2.jar 
gsutil cp gs://my-bucket/jars/guava-18.0.jar /usr/lib/hadoop/lib/ 

,我建我的星火應用程序JAR作爲脂肪罐子,用下面的Maven配置:

<dependency> 
     <groupId>com.google.apis</groupId> 
     <artifactId>google-api-services-storage</artifactId> 
     <version>v1-rev97-1.22.0</version> 
    </dependency> 
    <dependency> 
     <groupId>com.google.cloud.bigdataoss</groupId> 
     <artifactId>gcs-connector</artifactId> 
     <version>1.6.0-hadoop2</version> 
    </dependency>