Unable to use embedded-jetty in Android

2019-08-28 13:37发布

问题:

I am trying to embed the latest Jetty in android. But it is not working.

I am trying to make Jetty listen to a custom incoming HTTP method, NOTIFY. It works in desktop, now I am trying to import it to Andoird

Here is my code.

package com.example.arjun.hellotest;

import android.util.Log;

import java.io.IOException;
import java.io.BufferedReader;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.eclipse.jetty.server.Request;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.server.handler.AbstractHandler;

public class HelloWorld extends AbstractHandler
{
    @Override
    public void handle( String target,
                        Request baseRequest,
                        HttpServletRequest request,
                        HttpServletResponse response ) throws IOException,
                                                      ServletException
    {
        // Declare response encoding and types
        response.setContentType("text/html; charset=utf-8");

        // Declare response status code
        response.setStatus(HttpServletResponse.SC_OK);

        // Write back response
        response.getWriter().println("<h1>Hello World</h1>");

        // Inform jetty that this request has now been handled
        baseRequest.setHandled(true);

        String requestMethod = baseRequest.getMethod().toUpperCase();

        StringBuffer jb = new StringBuffer();
        String line = null;

        Map<String, String> map = new HashMap<String, String>();

        try {

            switch (requestMethod) {

                case "POST":
                    // do post logic
                    Log.w("JettyTest", "Handle POST request");
                    break;

                case "NOTIFY":
                    // do notify logic
                    Log.w("JettyTest", "Handle NOTIFY request");

                    Enumeration headerNames = request.getHeaderNames();
                    while (headerNames.hasMoreElements()) {
                        String key = (String) headerNames.nextElement();
                        String value = request.getHeader(key);                        
                        map.put(key, value);

                    }                 

                    for (String key : map.keySet()) {
                        Log.w("JettyTest", key + ": " + map.get(key));
                    }

                    Log.w("JettyTest", "Remote: "+request.getRemoteHost()+":"+request.getRemotePort());

                    BufferedReader reader = request.getReader();
                    while ((line = reader.readLine()) != null)
                        jb.append(line);

                    Log.w("JettyTest", jb.toString());
                    break;

                case "GET":
                    // do get logic
                    Log.w("JettyTest", "Handle GET request");
                    break;

                // so on.....

                default:
                    // do default
                    Log.w("JettyTest", "NOT IMPLEMENTED");

            }

        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public static void main( String[] args ) throws Exception
    {
        Runnable runnable = new Runnable() {
        @Override
        public void run() {
            Server server = new Server(8082);
            try {
                server.getConnectors()[0].getConnectionFactory(HttpConnectionFactory.class);
                server.setHandler(new HelloWorld());

                server.start();
                Log.w("JettyTest", "Server Started");
                server.join();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        };
        new Thread(runnable).start();
    }
}

I am getting 1 error

  1. Error:Execution failed for task ':app:transformDexArchiveWithExternalLibsDexMergerForDebug'.

    java.lang.RuntimeException: java.lang.RuntimeException: com.android.builder.dexing.DexArchiveMergerException: Unable to merge dex

(I went through this SO but I still get the same error after following every suggestion)


In AndroidManifest file

<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.CHANGE_WIFI_MULTICAST_STATE" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />

In my buildgradel file

apply plugin: 'com.android.application'

android {
    compileSdkVersion 26
    defaultConfig {
        applicationId "com.example.arjun.hellotest"
        minSdkVersion 22
        targetSdkVersion 26
        versionCode 1
        versionName "1.0"
        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }
}
repositories {
    mavenCentral()
}

dependencies {
    implementation fileTree(include: ['*.jar'], dir: 'libs')
    implementation 'com.android.support:appcompat-v7:26.1.0'
    implementation 'com.android.support.constraint:constraint-layout:1.0.2'
    implementation 'com.android.support:design:26.1.0'
    testImplementation 'junit:junit:4.12'
    androidTestImplementation 'com.android.support.test:runner:1.0.1'
    androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.1'
    implementation files('libs/jetty-all-uber.jar')
}