I wanna to create an HTTP server in Android. I want to use com.sun.net.httpserver in this program. In your opinion, Is it possible to use this package in Android program? I wrote a service to do this. My program is as fallow:
import android.app.Notification;
import android.app.NotificationManager;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.graphics.drawable.BitmapDrawable;
import android.net.Uri;
import android.os.IBinder;
import android.util.Log;
import android.widget.Toast;
import com.sun.net.httpserver.HttpServer;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.util.concurrent.Executors;
public class HSMainService extends Service {
//region constants
public static final int MY_NOTIFICATION_ID = 1;
public static final int SERVERPORT = 8080;
//endregion
//************************
//region instance variables
private String TAG;
private Uri soundURI = Uri
.parse("android.resource://com.ebcompany.hs4/"
+ R.raw.alarm_rooster);
private long[] mVibratePattern = { 0, 200, 200, 300 };
private HttpServer server;
//endregion
//************************
//region constructors
public HSMainService() {
//TAG = getApplicationContext().getString(R.string.log_message_tag);
}
//endregion
//************************
//region override methods
@Override
public IBinder onBind(Intent intent) {
// TODO: Return the communication channel to the service.
throw new UnsupportedOperationException("Not yet implemented");
}
// This is the old onStart method that will be called on the pre-2.0
// platform. On 2.0 or later we override onStartCommand() so this
// method will not be called.
@Override
public void onStart(Intent intent, int startId) {
//handleCommand(intent);
Log.i(TAG, "onStart");
Toast.makeText(getApplicationContext(), "onStart", Toast.LENGTH_LONG).show();
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
//handleCommand(intent);
// We want this service to continue running until it is explicitly
// stopped, so return sticky.
Log.i(TAG, "onStartCommand");
//Intent in = new Intent(getApplicationContext(), TestActivity.class);
//in.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
//startActivity(in);
//Toast.makeText(getApplicationContext(), "onStartCommand", Toast.LENGTH_LONG).show();
return START_STICKY;
}
@Override
public void onCreate() {
super.onCreate();
Context cntx = getApplicationContext();
TAG = cntx.getString(R.string.log_message_tag);
Log.i(TAG, "Service creating");
final Notification.Builder notificationBuilder = new Notification.Builder(getApplicationContext())
.setContentInfo("HS4")
.setSmallIcon(R.drawable.icon)
.setContentTitle(cntx.getString(R.string.notification_content_title))
.setContentText(cntx.getString(R.string.notification_content_text))
.setTicker(cntx.getString(R.string.notification_tiker_text))
.setSound(soundURI)
.setOngoing(true)
.setLargeIcon((((BitmapDrawable) this.getResources().getDrawable(R.drawable.fire_eye_alien)).getBitmap()));
final NotificationManager mNotificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
notificationBuilder.setWhen(System.currentTimeMillis());
mNotificationManager.notify(MY_NOTIFICATION_ID,
notificationBuilder.build());
try {
server = HttpServer.create(new InetSocketAddress(SERVERPORT), 0);
server.createContext("IS2", new IS2Handler());
server.createContext("DSP", new DSPHandler());
server.setExecutor(Executors.newFixedThreadPool(0x5) ); // creates a default executor
server.start();
} catch (IOException e) {
e.printStackTrace();
}
}
@Override
public void onDestroy() {
super.onDestroy();
Log.i(TAG, "Service destroying");
//server.stop(0x1);
}
//endregion
//************************
}
When I run this program I get this error:
08-02 04:24:37.233 2994-2994/com.ebcompany.hs4 I/dalvikvm﹕ Could not find method sun.misc.Service.providers, referenced from method com.sun.net.httpserver.spi.HttpServerProvider.loadProviderAsService
08-02 04:24:37.233 2994-2994/com.ebcompany.hs4 W/dalvikvm﹕ VFY: unable to resolve static method 421: Lsun/misc/Service;.providers (Ljava/lang/Class;Ljava/lang/ClassLoader;)Ljava/util/Iterator;
08-02 04:24:37.233 2994-2994/com.ebcompany.hs4 E/dalvikvm﹕ Could not find class 'sun.misc.ServiceConfigurationError', referenced from method com.sun.net.httpserver.spi.HttpServerProvider.loadProviderFromProperty
08-02 04:24:37.233 2994-2994/com.ebcompany.hs4 W/dalvikvm﹕ VFY: unable to resolve new-instance 155 (Lsun/misc/ServiceConfigurationError;) in Lcom/sun/net/httpserver/spi/HttpServerProvider;
08-02 04:24:37.233 2994-2994/com.ebcompany.hs4 E/dalvikvm﹕ Could not find class 'sun.misc.ServiceConfigurationError', referenced from method com.sun.net.httpserver.spi.HttpServerProvider.loadProviderFromProperty
08-02 04:24:37.233 2994-2994/com.ebcompany.hs4 W/dalvikvm﹕ VFY: unable to resolve new-instance 155 (Lsun/misc/ServiceConfigurationError;) in Lcom/sun/net/httpserver/spi/HttpServerProvider;
08-02 04:24:37.233 2994-2994/com.ebcompany.hs4 E/dalvikvm﹕ Could not find class 'sun.misc.ServiceConfigurationError', referenced from method com.sun.net.httpserver.spi.HttpServerProvider.loadProviderFromProperty
08-02 04:24:37.233 2994-2994/com.ebcompany.hs4 W/dalvikvm﹕ VFY: unable to resolve new-instance 155 (Lsun/misc/ServiceConfigurationError;) in Lcom/sun/net/httpserver/spi/HttpServerProvider;
08-02 04:24:37.233 2994-2994/com.ebcompany.hs4 E/dalvikvm﹕ Could not find class 'sun.misc.ServiceConfigurationError', referenced from method com.sun.net.httpserver.spi.HttpServerProvider.loadProviderFromProperty
08-02 04:24:37.233 2994-2994/com.ebcompany.hs4 W/dalvikvm﹕ VFY: unable to resolve new-instance 155 (Lsun/misc/ServiceConfigurationError;) in Lcom/sun/net/httpserver/spi/HttpServerProvider;
08-02 04:24:37.233 2994-2994/com.ebcompany.hs4 W/dalvikvm﹕ threadid=1: thread exiting with uncaught exception (group=0xacd19b20)
08-02 04:24:37.233 2994-2994/com.ebcompany.hs4 E/AndroidRuntime﹕ FATAL EXCEPTION: main
Process: com.ebcompany.hs4, PID: 2994
java.lang.NoClassDefFoundError: sun.misc.Service
at com.sun.net.httpserver.spi.HttpServerProvider.loadProviderAsService(HttpServerProvider.java:82)
at com.sun.net.httpserver.spi.HttpServerProvider.access$200(HttpServerProvider.java:27)
at com.sun.net.httpserver.spi.HttpServerProvider$1.run(HttpServerProvider.java:144)
at java.security.AccessController.doPrivileged(AccessController.java:45)
at com.sun.net.httpserver.spi.HttpServerProvider.provider(HttpServerProvider.java:139)
at com.sun.net.httpserver.HttpServer.create(HttpServer.java:110)
at com.ebcompany.hs4.HSMainService.onCreate(HSMainService.java:93)
at android.app.ActivityThread.handleCreateService(ActivityThread.java:2572)
at android.app.ActivityThread.access$1800(ActivityThread.java:135)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1278)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:136)
at android.app.ActivityThread.main(ActivityThread.java:5017)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:515)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:779)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:595)
at dalvik.system.NativeStart.main(Native Method)
How can I solve this problem?
As of 2021, I don't think the answers provided here give a straight forward solution. This is what worked for me:
jar file with com.sun.net.httpserver... classes AND other classes that are used by the abovejar file in order to be able to import them in your java files in your app<uses-permission android:name="android.permission.INTERNET" />Procedure:
jar file into your app's libs folder (in my case, c:\Android Projects\<Project Name>\app\libs). Where do you find such a file? In any java distribution, so in my case I simply used the rt.jar file from my Android Studio's jre\libs folder (in my case C:\Android Studio\jre\jre\lib\rt.jar). You may frown upon the fact that that is a 60 MB file, but the resulting apk was not significantly bigger than without the httpserver, so I assume the compiler only takes what it needs plus all dependencies.
rt.jar file into app/libs, it should appear in your project view, if not, right click the app icon and click Reload from Disk (see image 2)

rt.jar file and select Add As Library (see image 3)

I have tried stripping down the rt.jar file to something smaller, but even though my app could compile and run, the first instance where a method was called using any of the imported classes from com.sun.net.*, the app would crash (as in CRASH, not raise an exception). Thus you better include the entire rt.jar file. The example below taken from Simple HTTP server in Java using only Java SE API
Now you can import
import com.sun.net.httpserver.HttpExchange;
import com.sun.net.httpserver.HttpHandler;
import com.sun.net.httpserver.HttpServer;
and in your app's Activity class, create a simple http server the following way:
HttpServer server;
static class MyHandler implements HttpHandler {
@Override
public void handle(HttpExchange t) throws IOException {
System.out.println(t.toString());
String response = "This is the response";
t.sendResponseHeaders(200, response.length());
OutputStream os = t.getResponseBody();
os.write(response.getBytes());
os.close();
}
}
...
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
(new AsyncTask<String, Void, String>() {
@Override
protected String doInBackground(String... params) {
try {
server = HttpServer.create(new InetSocketAddress(8001), 0);
server.createContext("/ho", new MyHandler());
server.setExecutor(null);
server.start();
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
}).execute("");
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With