2017-10-20 18 views
0

BLOBストレージにアクセスするためにhttpでトリガされるAzure関数(Javaで書かれています)があります。コードはmavenでコンパイルされますが、ローカルで実行してCURLから投稿を送信すると、com.microsoft.azure.storage.CloudStorageAccountが見つからないために発生したClassNotFound例外のため、ランタイムがクラッシュします。 azure-storage(バージョン6.0.0)は、POMファイルの依存としてリストされます。関連する.jarファイルはどこにあるべきなのでしょうか?Javaのazure関数からBLOBストレージを使用するには

Javaの紺色の機能に関する洞察は高く評価されます。

答えて

0

を動作するかどうか私に教えてください、私はあなたが作成、実行、およびデプロイするために、このofficial tutorialを以下の示唆あなたのjava azure function

Functionクラス:

package com.fabrikam.functions; 

import com.microsoft.azure.serverless.functions.annotation.*; 
import com.microsoft.azure.serverless.functions.ExecutionContext; 

import com.microsoft.azure.storage.*; 
import com.microsoft.azure.storage.blob.*; 

/** 
* Hello function with HTTP Trigger. 
*/ 
public class Function { 

    // Configure the connection-string with your values 
    public static final String storageConnectionString = 
      "DefaultEndpointsProtocol=http;" + 
        "AccountName=jaygong;" + 
        "AccountKey=bmrgAHzDrL8FsbQOJP0xnYYNXrNOmfSZyBdzedlFG/famIHK9gJB/UUQzWbQ6DB/dq7zPZ/YMrk3bMcO+1hjrA=="; 

    @FunctionName("hello") 
    public String hello(@HttpTrigger(name = "req", methods = {"get", "post"}, authLevel = AuthorizationLevel.ANONYMOUS) String req, 
         ExecutionContext context) { 

     try { 
      // Retrieve storage account from connection-string. 
      CloudStorageAccount storageAccount = CloudStorageAccount.parse(storageConnectionString); 

      // Create the blob client. 
      CloudBlobClient blobClient = storageAccount.createCloudBlobClient(); 

      // Get a reference to a container. 
      // The container name must be lower case 
      CloudBlobContainer container = blobClient.getContainerReference(req); 

      // Create the container if it does not exist. 
      container.createIfNotExists(); 

      return String.format("Hello, I get container name : %s!", container.getName()); 

     } catch (Exception e) { 
      // Output the stack trace. 
      e.printStackTrace(); 
      return "Access Error!"; 
     } 
    } 
} 

のpom.xml:

<?xml version="1.0" encoding="UTF-8"?> 
<project xmlns="http://maven.apache.org/POM/4.0.0" 
     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
     xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 
    <modelVersion>4.0.0</modelVersion> 

    <groupId>com.fabrikam.functions</groupId> 
    <artifactId>fabrikam-functions</artifactId> 
    <version>1.0-SNAPSHOT</version> 
    <packaging>jar</packaging> 

    <name>Azure Java Functions</name> 

    <properties> 
     <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> 
     <maven.compiler.source>1.8</maven.compiler.source> 
     <maven.compiler.target>1.8</maven.compiler.target> 
     <functionAppName>fabrikam-functions-20171017112209094</functionAppName> 
    </properties> 

    <dependencies> 
     <dependency> 
      <groupId>com.microsoft.azure</groupId> 
      <artifactId>azure-functions-java-core</artifactId> 
      <version>1.0.0-beta-1</version> 
     </dependency> 

     <!-- https://mvnrepository.com/artifact/com.microsoft.azure/azure-storage --> 
     <dependency> 
      <groupId>com.microsoft.azure</groupId> 
      <artifactId>azure-storage</artifactId> 
      <version>6.0.0</version> 
     </dependency> 

     <!-- Test --> 
     <dependency> 
      <groupId>junit</groupId> 
      <artifactId>junit</artifactId> 
      <version>4.12</version> 
      <scope>test</scope> 
     </dependency> 
    </dependencies> 

    <build> 
     <pluginManagement> 
      <plugins> 
       <plugin> 
        <artifactId>maven-resources-plugin</artifactId> 
        <version>3.0.2</version> 
       </plugin> 
       <plugin> 
        <groupId>com.microsoft.azure</groupId> 
        <artifactId>azure-functions-maven-plugin</artifactId> 
        <version>0.1.4</version> 
       </plugin> 
      </plugins> 
     </pluginManagement> 

     <plugins> 
      <plugin> 
       <groupId>com.microsoft.azure</groupId> 
       <artifactId>azure-functions-maven-plugin</artifactId> 
       <configuration> 
        <resourceGroup>java-functions-group</resourceGroup> 
        <appName>${functionAppName}</appName> 
        <region>westus2</region> 
        <appSettings> 
         <property> 
          <name>FUNCTIONS_EXTENSION_VERSION</name> 
          <value>beta</value> 
         </property> 
        </appSettings> 
       </configuration> 
       <executions> 
        <execution> 
         <id>package-functions</id> 
         <goals> 
          <goal>package</goal> 
         </goals> 
        </execution> 
       </executions> 
      </plugin> 
      <plugin> 
       <artifactId>maven-resources-plugin</artifactId> 
       <executions> 
        <execution> 
         <id>copy-resources</id> 
         <phase>package</phase> 
         <goals> 
          <goal>copy-resources</goal> 
         </goals> 
         <configuration> 
          <overwrite>true</overwrite> 
          <outputDirectory>${project.build.directory}/azure-functions/${functionAppName} 
          </outputDirectory> 
          <resources> 
           <resource> 
            <directory>${project.basedir}</directory> 
            <includes> 
             <include>host.json</include> 
             <include>local.settings.json</include> 
            </includes> 
           </resource> 
          </resources> 
         </configuration> 
        </execution> 
       </executions> 
      </plugin> 
     </plugins> 

    </build> 

</project> 

その後のjarパッケージにあなたのMavenプロジェクトをパックするコマンドmvn clean packageを使用します。

enter image description here

ローカルに紺碧の機能を実行するために使用するコマンドmvn azure-functions:run

enter image description here


アップデート回答:

私は紺碧の機能を実行し、あなたが言ったように同じ例外を再現。いくつかの研究の後

java.lang.NoClassDefFoundError: com/microsoft/azure/storage/CloudStorageAccount

Exception: 
Stack: java.lang.reflect.InvocationTargetException 
[10/25/2017 2:48:44 AM]   at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 
[10/25/2017 2:48:44 AM]   at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) 
[10/25/2017 2:48:44 AM]   at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)[10/25/2017 2:48:44 AM]   at java.lang.reflect.Method.invoke(Method.java:498) 
[10/25/2017 2:48:44 AM]   at com.microsoft.azure.webjobs.script.broker.JavaMethodInvokeInfo.invoke(JavaMethodInvokeInfo.java:19) 
[10/25/2017 2:48:44 AM]   at com.microsoft.azure.webjobs.script.broker.JavaMethodExecutor.execute(JavaMethodExecutor.java:34) 
[10/25/2017 2:48:44 AM]   at com.microsoft.azure.webjobs.script.broker.JavaFunctionBroker.invokeMethod(JavaFunctionBroker.java:40) 
[10/25/2017 2:48:44 AM]   at com.microsoft.azure.webjobs.script.handler.InvocationRequestHandler.execute(InvocationRequestHandler.java:33) 
[10/25/2017 2:48:44 AM]   at com.microsoft.azure.webjobs.script.handler.InvocationRequestHandler.execute(InvocationRequestHandler.java:10) 
[10/25/2017 2:48:44 AM]   at com.microsoft.azure.webjobs.script.handler.MessageHandler.handle(MessageHandler.java:41) 
[10/25/2017 2:48:44 AM]   at com.microsoft.azure.webjobs.script.JavaWorkerClient$StreamingMessagePeer.lambda$onNext$0(JavaWorkerClient.java:84) 
[10/25/2017 2:48:44 AM]   at java.util.concurrent.ForkJoinTask$AdaptedRunnableAction.exec(ForkJoinTask.java:1386) 
[10/25/2017 2:48:44 AM]   at java.util.concurrent.ForkJoinTask.doExec(ForkJoinTask.java:289) 
[10/25/2017 2:48:44 AM]   at java.util.concurrent.ForkJoinPool$WorkQueue.runTask(ForkJoinPool.java:1056) 
[10/25/2017 2:48:44 AM]   at java.util.concurrent.ForkJoinPool.runWorker(ForkJoinPool.java:1692) 
[10/25/2017 2:48:44 AM]   at java.util.concurrent.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:157) 
[10/25/2017 2:48:44 AM] Caused by: java.lang.NoClassDefFoundError: com/microsoft/azure/storage/CloudStorageAccount 
[10/25/2017 2:48:44 AM]   at com.fabrikam.functions.Function.hello(Function.java:26) 
[10/25/2017 2:48:44 AM]   ... 16 more 
[10/25/2017 2:48:44 AM] Caused by: java.lang.ClassNotFoundException: com.microsoft.azure.storage.CloudStorageAccount 
[10/25/2017 2:48:44 AM]   at java.net.URLClassLoader.findClass(URLClassLoader.java:381) 
[10/25/2017 2:48:44 AM]   at java.lang.ClassLoader.loadClass(ClassLoader.java:424) 
[10/25/2017 2:48:44 AM]   at java.lang.ClassLoader.loadClass(ClassLoader.java:357) 
[10/25/2017 2:48:44 AM]   ... 17 more 
[10/25/2017 2:48:44 AM] . 
[10/25/2017 2:48:44 AM] Function had errors. See Azure WebJobs SDK dashboard for details. Instance ID is '3450abda-99a0-4d75-add2-a7bc48a0cb51' 
[10/25/2017 2:48:44 AM] System.Private.CoreLib: Exception while executing function: Functions.hello. System.Private.CoreLib: Result: 

、私は瓶がdependent jar packagesせずにパッケージ化するのでそれがあったことが分かりました。

だから、私はその後、コマンドmvn-clean-packageを使用して、生成された2つのJARファイルが表示されますしてください私のpom.xml

<plugin> 
       <artifactId>maven-assembly-plugin</artifactId> 
       <configuration> 
        <descriptorRefs> 
         <descriptorRef>jar-with-dependencies</descriptorRef> 
        </descriptorRefs> 
        <archive> 
         <manifest> 
          <mainClass>Your main class path</mainClass> 
         </manifest> 
        </archive> 
       </configuration> 
       <executions> 
        <execution> 
         <id>make-assembly</id> 
         <phase>package</phase> 
         <goals> 
          <goal>single</goal> 
         </goals> 
        </execution> 
       </executions> 
      </plugin> 

に以下のような構成のスニペットを追加しました。

enter image description here

一つは、それがdependent jar packagesが含まれていないということで、2つ目は、dependent jar packagesが含まれています。

は、パスに fabrikam-functions-1.0-SNAPSHOT-jar-with-dependencies jarファイルを移動し

:私にとって${project.basedir}/target/azure-functions/${function-app-name}/

は、それがE:\TestAzureFunction\fabrikam-functions\target\azure-functions\fabrikam-functions-20171017112209094のように見えます。

jarファイルの名前をfabrikam-functions-1.0-SNAPSHOTに忘れないようにしてください。

最後に、azure関数を正常に実行し、url:http://localhost:7071/api/mongoで出力結果を取得します。

enter image description here

また、あなたは紺碧function maven plugin詳細設定の詳細については、このgithub docを参照することができます。

お手伝いします。

+0

実際に関数を実行すると(上記の関数がロードされていることを示しています)、遭遇したのと同じエラーでクラッシュすることがわかります。 CURLを使用してHTTPメッセージを送信します。クラッシュしない場合は、MSストレージライブラリがローカルマシン上のどこにあるか教えてください。 –

+0

CURLを使用して関数を実行できるかどうか不思議です。私はローカルでJavaコードによく似たC#関数を作成して実行することができ、Azure C#ライブラリ(Visual Studioにアセンブリを手動で追加する必要がありました)を使用して期待どおりに動作します。これは、私が遭遇した問題が実際に私のMaven環境の何らかの特異性に起因すると考えるようになり、私はMavenをよく知りません。私はC#に変換したくない他のJavaコードがあるので、私はJava関数を使いたいと思います。あなたが成功したなら、私に知らせてください。 –

+0

@JackCopperあまりにも遅く返信して申し訳ありません、私の答えを更新する時間をください。ありがとうございます。 –

0

使用している方法や種類について詳しく説明できますか?出力バインディングを行うには、OutputBinding<T>クラスを正しい注釈とともに使用する必要があります。ここで私はちょうどあなたが言及したものに似行うためにテスト1の例です:@BlobOutput属性とOutputBindingタイプは(Stringまたはbyte []かもしれないが、byte []を行う場合、私はあなたにも設定する必要があると考えてい

@FunctionName("hello") 
public String hello(
     @HttpTrigger(name = "req", methods = { 
       "post" }, authLevel = AuthorizationLevel.ANONYMOUS) String req, 
     ExecutionContext context, @BlobOutput(name = "blob", connection = "StorageAccount", path = "test/foo.txt")OutputBinding<String> blob) 
     { 
    blob.setValue("hello world"); 
    return String.format("Hello, %s!", req); 
} 

お知らせdataTypeと@BlobAttribute上に「バイナリ」。

は、それはあなたのニーズによると

+0

ユース・ケースは、コンテナIDと特定のファイル名がリクエスト・ヘッダーにあります。 blobは、渡されたコンテナの階層内の固定された場所にある任意のファイル(テキスト)です。私はいくつかの行を読んでから、BLOBにメタデータを追加する必要があります。あなたの回答から、他の注釈(たとえば、ストリームを使用する必要があると思われます)を見ていることが指摘されていますが、依頼ヘッダーから必要なパラメータと接続パラメータを取得するための基本にはまだ苦労しています。 –

関連する問題