5

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

2
  • Wait, so is there really no way to just add my code to the function app trigger events? Also I have no idea what a "Docker Image" is. This is my first time ever using azure Commented Jul 3, 2019 at 23:23
  • Hi,does my answer helps you? Commented Jul 5, 2019 at 7:20

2 Answers 2

4

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.

Sign up to request clarification or add additional context in comments.

3 Comments

Getting close, but see the issue is you are not using any external libraries like json and apache commons, which is where my issue resides. I put in the snippet of code into my pom, but I still got the same errors. Maybe I have to change my dependencies?
@armnhammer Have you seen some error logs related to the lib you used?
Sorry I am late to responding, but I figured it out thanks to you
1

Here is the folder structure of an Azure functions Java project:

FunctionsProject
 | - src
 | | - main
 | | | - java
 | | | | - FunctionApp
 | | | | | - MyFirstFunction.java
 | | | | | - MySecondFunction.java
 | - target
 | | - azure-functions
 | | | - FunctionApp
 | | | | - FunctionApp.jar
 | | | | - host.json
 | | | | - MyFirstFunction
 | | | | | - function.json
 | | | | - MySecondFunction
 | | | | | - function.json
 | | | | - bin
 | | | | - lib
 | - pom.xml

The FunctionApp in the target directory is what gets deployed to your function app in Azure. Java libraries should exist in lib folder.

You can refer to this guide to deploy your function with Java and Maven.

1 Comment

The program did not come with a "lib" folder itself so I added one and put my jars in there, but it did not work.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.