0

I have a cloud function that is triggered by pub/sub topic. Now when the function gets called I want to put message data to my server using rest API. I am using 'com.loopj.android:android-async-http:1.4.4' dependency to call API. my function deploys successfully but when it triggers it will show the following error.

Failed to execute com.example.Example
java.lang.NoClassDefFoundError: android/os/Handler
    at com.example.Example.callapi(Example.java:44)
    at com.example.Example.accept(Example.java:25)
    at com.example.Example.accept(Example.java:15)
    at com.google.cloud.functions.invoker.BackgroundFunctionExecutor$TypedFunctionExecutor.serviceLegacyEvent(BackgroundFunctionExecutor.java:285)
    at com.google.cloud.functions.invoker.BackgroundFunctionExecutor.lambda$serviceLegacyEvent$8(BackgroundFunctionExecutor.java:375)
    at com.google.cloud.functions.invoker.BackgroundFunctionExecutor.runWithContextClassLoader(BackgroundFunctionExecutor.java:382)
    at com.google.cloud.functions.invoker.BackgroundFunctionExecutor.serviceLegacyEvent(BackgroundFunctionExecutor.java:375)
    at com.google.cloud.functions.invoker.BackgroundFunctionExecutor.service(BackgroundFunctionExecutor.java:330)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:790)
    at org.eclipse.jetty.servlet.ServletHolder.handle(ServletHolder.java:755)
    at org.eclipse.jetty.servlet.ServletHandler.doHandle(ServletHandler.java:547)
    at org.eclipse.jetty.server.handler.ScopedHandler.nextHandle(ScopedHandler.java:233)
    at org.eclipse.jetty.server.handler.ContextHandler.doHandle(ContextHandler.java:1297)
    at org.eclipse.jetty.server.handler.ScopedHandler.nextScope(ScopedHandler.java:188)
    at org.eclipse.jetty.servlet.ServletHandler.doScope(ServletHandler.java:485)
    at org.eclipse.jetty.server.handler.ScopedHandler.nextScope(ScopedHandler.java:186)
    at org.eclipse.jetty.server.handler.ContextHandler.doScope(ContextHandler.java:1212)
    at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:141)
    at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:127)
    at com.google.cloud.functions.invoker.runner.Invoker$NotFoundHandler.handle(Invoker.java:392)
    at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:127)
    at org.eclipse.jetty.server.Server.handle(Server.java:500)
    at org.eclipse.jetty.server.HttpChannel.lambda$handle$1(HttpChannel.java:383)
    at org.eclipse.jetty.server.HttpChannel.dispatch(HttpChannel.java:547)
    at org.eclipse.jetty.server.HttpChannel.handle(HttpChannel.java:375)
    at org.eclipse.jetty.server.HttpConnection.onFillable(HttpConnection.java:270)
    at org.eclipse.jetty.io.AbstractConnection$ReadCallback.succeeded(AbstractConnection.java:311)
    at org.eclipse.jetty.io.FillInterest.fillable(FillInterest.java:103)
    at org.eclipse.jetty.io.ChannelEndPoint$2.run(ChannelEndPoint.java:117)
    at org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.runTask(EatWhatYouKill.java:336)
    at org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.doProduce(EatWhatYouKill.java:313)
    at org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.tryProduce(EatWhatYouKill.java:171)
    at org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.run(EatWhatYouKill.java:129)
    at org.eclipse.jetty.util.thread.ReservedThreadExecutor$ReservedThread.run(ReservedThreadExecutor.java:388)
    at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:806)
    at org.eclipse.jetty.util.thread.QueuedThreadPool$Runner.run(QueuedThreadPool.java:938)
    at java.base/java.lang.Thread.run(Thread.java:829)
Caused by: java.lang.ClassNotFoundException: android.os.Handler
    at java.base/java.net.URLClassLoader.findClass(URLClassLoader.java:471)
    at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:589)
    at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:522)
    ... 37 more

Cloud function java file--

package com.example;

import com.example.Example.PubSubMessage;
import com.google.cloud.functions.BackgroundFunction;
import com.google.cloud.functions.Context;
import java.util.Base64;
import java.util.Map;
import java.util.logging.Logger;

import com.loopj.android.http.AsyncHttpClient;
import com.loopj.android.http.AsyncHttpResponseHandler;
import com.loopj.android.http.JsonHttpResponseHandler;
import com.loopj.android.http.RequestParams;

public class Example implements BackgroundFunction<PubSubMessage> {
  private static final Logger logger = Logger.getLogger(Example.class.getName());

  @Override
  public void accept(PubSubMessage message, Context context) {
    String data = message.data != null
      ? new String(Base64.getDecoder().decode(message.data))
      : "Hello, World";
    logger.info(data);

    callapi(data);
  }

  public static class PubSubMessage {
    String data;
    Map<String, String> attributes;
    String messageId;
    String publishTime;
  }
  

   public void callapi(String data) {
     
       
        RequestParams rp = new RequestParams();
        rp.add("data", data);

        AsyncHttpClient client = new AsyncHttpClient();
        client.post("http://198.198.198.1/jhd/v1/jhd_controllers/addPurchase", rp, new JsonHttpResponseHandler());   
    }
}

pom.xml file--

<?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>cloudfunctions</groupId>
  <artifactId>pubsub-function</artifactId>
  <version>1.0-SNAPSHOT</version>

  <properties>
    <maven.compiler.target>11</maven.compiler.target>
    <maven.compiler.source>11</maven.compiler.source>
  </properties>

  <dependencies>
    <dependency>
    <groupId>com.loopj.android</groupId>
    <artifactId>android-async-http</artifactId>
    <version>1.4.4</version>
    </dependency>

<!--
    <dependency>
        <groupId>org.apache.httpcomponents</groupId>
        <artifactId>httpclient</artifactId>
        <version>4.3.4</version>
    </dependency>
-->

    <dependency>
      <groupId>com.google.cloud.functions</groupId>
      <artifactId>functions-framework-api</artifactId>
      <version>1.0.1</version>
      <type>jar</type>
    </dependency>
  </dependencies>

  <!-- Required for Java 11 functions in the inline editor -->
  <build>
    <plugins>
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-compiler-plugin</artifactId>
        <version>3.8.1</version>
        <configuration>
          <excludes>
            <exclude>.google/</exclude>
          </excludes>
        </configuration>
      </plugin>
    </plugins>
  </build>
</project>
Donnald Cucharo
  • 3,866
  • 1
  • 10
  • 17

1 Answers1

1

What you're using is an Android HTTP Client. It's not possible to use Android Libraries in Java Cloud Functions. As you can see in the documentation, the entire execution environment is based on Ubuntu Image and Java 11. It doesn't include the Android environment.

Even if you look at the system packages included by default, you won't be able to find the packages needed to run Android Libraries.

The solution is to use a Java HTTP Client, like the one that's already built in Java 11. You're also free to choose alternative libraries, as there are many HTTP clients available out there that supports both Java and Android.

Donnald Cucharo
  • 3,866
  • 1
  • 10
  • 17
  • Thanks, Dondi for your support. Now I'm using the library for java11 and the code executes perfectly but it gives javax.net.ssl.SSLHandshakeException: Received fatal alert: handshake_failure exception. Can you please help me for this issue? – Viral Radadiya Jul 15 '21 at 06:18
  • @ViralRadadiya, it appears to be a new problem. This [answer](https://stackoverflow.com/a/59381416/7031308) might help you get started. Once you have enough information, please create a new question to isolate the problem. For now, if I addressed your original concern, then consider accepting my answer. – Donnald Cucharo Jul 15 '21 at 08:27