How to add my own code/function and external java libraries to azure function app

armnhammer :

I have written up some code to create a file when the code is running. My plan was to put this on Microsoft Azure function app on a recurring schedule, so it runs every hour or day. I will be using a timertrigger and have an HTTP request trigger in there too for testing, however, I do not know where to put in my own code to get it up and running as well as external java libraries.

The base code that is given when creating the function app work and runs with maven, but when I had created another function and put my own code in it would crash and say there were many errors with the external java libraries I used, JSON, JSON simple, and Apache Commons.

The end result I'm looking for is to be able to put my code in and have the program run on a schedule and create the file I want. For now, I am getting errors wherever I insert my code.

UPDATE: I think the issue might be with my external libraries that I am using, but I do not know why they would be causing an issue or how I would fix it. I need the external libraries to make my code work. I added them to the projects build path so they should work fine. It is giving me errors "package org.apache.commons.io does not exist" and so on for all the imported libraries

Jay Gong :

You could follow the guide provided by @Caiyi,or follow some detailed steps I did in the past.

For example, I want to use Azure blob storage sdk in my Java function app.

Function Class:

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=***;" +
                    "AccountKey=***";

    @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>

Then use command mvn clean package to pack your maven project into a jar package.

enter image description here

use command mvn azure-functions:run to run your Azure function locally.

enter image description here

Now,if you run the Azure function and you could see the below issue possibly.

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:

It because that the jar packaged without dependent jar packages.

So , please added the snippet of configuration as below into my 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>

Then use command mvn-clean-package and you will see two jar files generated.

enter image description here

One is that it does not contain dependent jar packages, and the second one contains dependent jar packages.

Move the fabrikam-functions-1.0-SNAPSHOT-jar-with-dependencies jar into the path:${project.basedir}/target/azure-functions/${function-app-name}/

For me ,it looks like E:\TestAzureFunction\fabrikam-functions\target\azure-functions\fabrikam-functions-20171017112209094.

Don't forget rename the jar to fabrikam-functions-1.0-SNAPSHOT.

Finally, run the azure function successfully and get the output result via the url: http://localhost:7071/api/hello.

enter image description here

In addition, you could refer to this github doc for more configuration details about azure function maven plugin.

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=145611&siteId=1