com.sun.jini.tool
Class ClassServer

java.lang.Object
  extended by java.lang.Thread
      extended by com.sun.jini.tool.ClassServer
All Implemented Interfaces:
Runnable

public class ClassServer
extends Thread

A simple HTTP server, for serving up JAR and class files.

The following items are discussed below:

Logging

This implementation uses the Logger named com.sun.jini.tool.ClassServer to log information at the following logging levels:

com.sun.jini.tool.ClassServer
Level Description
SEVERE failure to accept an incoming connection
WARNING failure to read the contents of a requested file, failure to find the message resource bundle, failure while executing the -stop option
INFO server startup and termination
CONFIG the JAR files being used for -trees
HANDLED failure reading an HTTP request or writing a response
FINE bad HTTP requests, HTTP requests for nonexistent files
FINER good HTTP requests

Examples for running ClassServer

This server can be run directly from the command line or as a nonactivatable service under the Service Starter.

An example of running directly from the command line is:

 % java -jar install_dir/lib/classserver.jar \
        -port 8081 -dir install_dir/lib-dl -verbose
 
where install_dir is the directory where the Apache River release is installed. This command places the class server on the (non-default) port 8081, which serves out the files under the (non-default) directory install_dir/lib-dl. The -verbose option also causes download attempts to be logged.

An example of running under the Service Starter is:

 % java -Djava.security.policy=start_policy \
        -jar install_dir/lib/start.jar \
        httpd.config
 

where start_policy is the name of a security policy file (not provided), and httpd.config is the following configuration file:

 import com.sun.jini.start.NonActivatableServiceDescriptor;
 import com.sun.jini.start.ServiceDescriptor;
 
 com.sun.jini.start {
 
   serviceDescriptors = new ServiceDescriptor[]{
     new NonActivatableServiceDescriptor(
       "",
       "httpd_policy",
       "install_dir/lib/classserver.jar",
       "com.sun.jini.tool.ClassServer",
       new String[]{"-port", "8081", "-dir", "install_dir/lib-dl", "-verbose"})
     };
 }
 
where httpd_policy is the name of a security policy file (not provided).

Author:
Sun Microsystems, Inc.

Nested Class Summary
private  class ClassServer.Task
          Simple daemon task thread
 
Nested classes/interfaces inherited from class java.lang.Thread
Thread.State, Thread.UncaughtExceptionHandler
 
Field Summary
private static String DEFAULT_DIR
          Default directory to serve files from on non-Windows OS
private static int DEFAULT_PORT
          Default HTTP port
private static String DEFAULT_WIN_DIR
          Default directory to serve files from on Windows
private  String[] dirs
          Directories to serve from
private  LifeCycle lifeCycle
          Life cycle control
private static Logger logger
           
private  Map map
          Map from String (JAR root) to JarFile[] (JAR class path)
private  FilePermission[] perms
          Read permission on dir and all subdirs, for each dir in dirs
private static boolean resinit
           
private static ResourceBundle resources
           
private  ServerSocket server
          Server socket to accept connections on
private  boolean stoppable
          Stoppable flag
private  boolean verbose
          Verbosity flag
 
Fields inherited from class java.lang.Thread
MAX_PRIORITY, MIN_PRIORITY, NORM_PRIORITY
 
Constructor Summary
ClassServer(int port, String dirlist, boolean trees, boolean verbose)
          Construct a server that does not support network shutdown.
ClassServer(int port, String dirlist, boolean trees, boolean verbose, boolean stoppable)
          Construct a server.
ClassServer(String[] args, LifeCycle lifeCycle)
          Construct a running server, accepting the same command line options supported by main, except for the -stop option.
 
Method Summary
private  void addJar(String jar, List jflist, Map jfmap)
          Add transitive Class-Path JARs to jflist.
private static String decode(String path)
          Decode escape sequences
private static char decode(String s, int i)
          Parse % HEX HEX from s starting at i
protected  void fileDownloaded(String fp, InetAddress addr)
          This method provides a way for subclasses to be notified when a file has been completely downloaded.
private static String getInput(Socket sock, boolean isRequest)
          Read the request/response and return the initial line.
 int getPort()
          Returns the port on which this server is listening.
private static String getString(String key)
           
private  void init(int port, String dirlist, boolean trees, boolean verbose, boolean stoppable, LifeCycle lifeCycle)
          Do the real work of the constructor.
static void main(String[] args)
          Command line interface for creating an HTTP server.
private static void print(String key, String val)
           
private static void print(String key, String[] vals)
           
private static boolean readLine(InputStream in, StringBuffer buf)
          Read up to CRLF, return false if EOF
 void run()
          Just keep looping, spawning a new thread for each incoming request.
 void terminate()
          Close the server socket, causing the thread to terminate.
 
Methods inherited from class java.lang.Thread
activeCount, checkAccess, clone, countStackFrames, currentThread, destroy, dumpStack, enumerate, getAllStackTraces, getContextClassLoader, getDefaultUncaughtExceptionHandler, getId, getName, getPriority, getStackTrace, getState, getThreadGroup, getUncaughtExceptionHandler, holdsLock, interrupt, interrupted, isAlive, isDaemon, isInterrupted, join, join, join, resume, setContextClassLoader, setDaemon, setDefaultUncaughtExceptionHandler, setName, setPriority, setUncaughtExceptionHandler, sleep, sleep, start, stop, stop, suspend, toString, yield
 
Methods inherited from class java.lang.Object
equals, finalize, getClass, hashCode, notify, notifyAll, wait, wait, wait
 

Field Detail

DEFAULT_PORT

private static int DEFAULT_PORT
Default HTTP port


DEFAULT_DIR

private static String DEFAULT_DIR
Default directory to serve files from on non-Windows OS


DEFAULT_WIN_DIR

private static String DEFAULT_WIN_DIR
Default directory to serve files from on Windows


logger

private static Logger logger

server

private ServerSocket server
Server socket to accept connections on


dirs

private String[] dirs
Directories to serve from


map

private Map map
Map from String (JAR root) to JarFile[] (JAR class path)


verbose

private boolean verbose
Verbosity flag


stoppable

private boolean stoppable
Stoppable flag


perms

private FilePermission[] perms
Read permission on dir and all subdirs, for each dir in dirs


lifeCycle

private LifeCycle lifeCycle
Life cycle control


resources

private static ResourceBundle resources

resinit

private static boolean resinit
Constructor Detail

ClassServer

public ClassServer(int port,
                   String dirlist,
                   boolean trees,
                   boolean verbose)
            throws IOException
Construct a server that does not support network shutdown. Use the start method to run it.

Parameters:
port - the port to use
dirlist - the list of directories to serve files from, with entries separated by the path-separator character
trees - true if files within JAR files should be served up
verbose - true if downloads should be logged
Throws:
IOException - if the server socket cannot be created
NullPointerException - if dir is null

ClassServer

public ClassServer(int port,
                   String dirlist,
                   boolean trees,
                   boolean verbose,
                   boolean stoppable)
            throws IOException
Construct a server. Use the start method to run it.

Parameters:
port - the port to use
dirlist - the list of directories to serve files from, with entries separated by the path-separator character
trees - true if files within JAR files should be served up
verbose - true if downloads should be logged
stoppable - true if network shutdown from the local host should be supported
Throws:
IOException - if the server socket cannot be created
NullPointerException - if dir is null

ClassServer

public ClassServer(String[] args,
                   LifeCycle lifeCycle)
            throws IOException
Construct a running server, accepting the same command line options supported by main, except for the -stop option.

Parameters:
args - command line options
lifeCycle - life cycle control object, or null
Throws:
IOException - if the server socket cannot be created
IllegalArgumentException - if a command line option is not understood
NullPointerException - if args or any element of args is null
Method Detail

init

private void init(int port,
                  String dirlist,
                  boolean trees,
                  boolean verbose,
                  boolean stoppable,
                  LifeCycle lifeCycle)
           throws IOException
Do the real work of the constructor.

Throws:
IOException

addJar

private void addJar(String jar,
                    List jflist,
                    Map jfmap)
             throws IOException
Add transitive Class-Path JARs to jflist.

Throws:
IOException

run

public void run()
Just keep looping, spawning a new thread for each incoming request.

Specified by:
run in interface Runnable
Overrides:
run in class Thread

terminate

public void terminate()
Close the server socket, causing the thread to terminate.


getPort

public int getPort()
Returns the port on which this server is listening.


readLine

private static boolean readLine(InputStream in,
                                StringBuffer buf)
                         throws IOException
Read up to CRLF, return false if EOF

Throws:
IOException

decode

private static char decode(String s,
                           int i)
Parse % HEX HEX from s starting at i


decode

private static String decode(String path)
Decode escape sequences


getInput

private static String getInput(Socket sock,
                               boolean isRequest)
                        throws IOException
Read the request/response and return the initial line.

Throws:
IOException

getString

private static String getString(String key)

print

private static void print(String key,
                          String val)

print

private static void print(String key,
                          String[] vals)

fileDownloaded

protected void fileDownloaded(String fp,
                              InetAddress addr)
This method provides a way for subclasses to be notified when a file has been completely downloaded.

Parameters:
fp - The path to the file that was downloaded.

main

public static void main(String[] args)
Command line interface for creating an HTTP server. The command line options are:
 [-port port] [-dir dirlist] [-dirs dirlist] [-stoppable] [-verbose] [-trees]
 
The default port is 8080; the default can be overridden with the -port option. The default directory on Windows is J: and the default on other systems is /vob/jive/lib-dl; the default can be overridden with the -dir or -dirs option, providing one or more directories separated by the path-separator character. All files under these directories (including all subdirectories) are served up via HTTP. If the pathname of a file is path relative to one of the top-level directories, then the file can be downloaded using the URL
 http://host:port/path
 
If a relative path matches a file under more than one top-level directory, the file under the first top-level directory with a match is used. No caching of directory contents or file contents is performed.

If the -stoppable option is given, the HTTP server can be shut down with a custom HTTP SHUTDOWN request originating from the local host. The command line options for stopping an existing HTTP server are:

 [-port port] -stop
 

If the -verbose option is given, then all attempts to download files are output.

The -trees option can be used to serve up individual files stored within JAR and zip files in addition to the files that are served up as described above. If the option is used, the server finds all JAR and zip files in the top-level directories (not in subdirectories). If the name of the JAR or zip file is name.jar or name.zip, then any individual file named file within it (or within the JAR or zip files referenced transitively in Class-Path manifest attributes), can be downloaded using a URL of the form:

 http://host:port/name/file
 
If multiple top-level directories have JAR or zip files with the same name, the file under the first top-level directory with a match is used. If a Class-Path element matches a file under more than one top-level directory, the file under the first top-level directory with a match is used. When this option is used, an open file descriptor and cached information is held for each JAR or zip file, for the life of the process.



Copyright 2007-2010, multiple authors.
Licensed under the Apache License, Version 2.0, see the NOTICE file for attributions.