github.com/emc-advanced-dev/unik@v0.0.0-20190717152701-a58d3e8e33b7/docs/getting_started_java.md (about)

     1  # Getting Started: OSv on Java Edition!
     2  
     3  In this tutorial we'll be:
     4    1. [installing UniK](getting_started_java.md#installing-unik)
     5    2. [writing a simple HTTP Daemon in Java](getting_started_java.md#write-a-java-http-server-using-maven)
     6    3. [compiling to a unikernel and launching an instance on Virtualbox](getting_started_java.md#compile-an-image-and-run-on-virtualbox)
     7  
     8  ### Installing UniK
     9  #### Prerequisites
    10  Ensure that each of the following are installed
    11  - [Docker](http://www.docker.com/) installed and running with at least 4GB available space for building images
    12  - [`jq`](https://stedolan.github.io/jq/)
    13  - [`make`](https://www.gnu.org/software/make/)
    14  - [Virtualbox](https://www.virtualbox.org/)
    15  - [Maven](https://maven.apache.org/download.cgi)
    16  
    17  #### Install, configure, and launch UniK
    18  1. Install UniK
    19    ```
    20    $ git clone https://github.com/solo-io/unik.git
    21    $ cd unik
    22    $ make
    23    ```
    24    note: `make` will take quite a few minutes the first time it runs. the UniK `Makefile` is pulling all of the Docker images that bundle UniK's dependencies.
    25  
    26    Then, place the `unik` executable in your `$PATH` to make running UniK commands easier:
    27    ```
    28    $ mv _build/unik /usr/local/bin/
    29    ```
    30  
    31  2. Configure a Host-Only Network on Virtualbox
    32    * Open Virtualbox
    33    * Open **Preferences** > **Network** > **Host-only Networks**
    34    * Click the green add button on the right side of the UI
    35    * Record the name of the new Host-Only adapter. You will need this in your UniK configuration
    36    * Ensure that the Virtualbox DHCP Server is Enabled for this Host-Only Network:
    37      * With the Host-Only Network selected, Click the edit button (screwdriver image)
    38      * In the **Adapter** tab, note the IPv4 address and netmask of the adapter.
    39      * In the **DHCP Server** tab, check the **Enable Server** box
    40      * Set **Server Address** an IP on the same subnet as the Adapter IP. For example, if the adapter IP is `192.168.100.1`, make set the DHCP server IP as `192.168.100.X`, where X is a number between 2-254.
    41      * Set **Server Mask** to the netmask you just noted
    42      * Set **Upper / Lower Address Bound** to a range of IPs on the same subnet. We recommend using the range `X-254` where X is one higher than the IP you used for the DHCP server itself. E.g., if your DHCP server is `192.168.100.2`, you can set the lower and upper bounds to `192.168.100.3` and `192.168.100.254`, respectively.
    43  
    44  3. Configure UniK daemon
    45    * Using a text editor, create and save the following to `$HOME/.unik/daemon-config.yaml`:
    46      
    47  ```yaml
    48  providers:
    49    virtualbox:
    50      - name: my-vbox
    51        adapter_type: host_only
    52        adapter_name: NEW_HOST_ONLY_ADAPTER
    53  ```
    54      
    55  replacing `NEW_HOST_ONLY_ADAPTER` with the name of the network adapter you created.
    56  
    57  4. Launch UniK and automatically deploy the *Virtualbox Instance Listener*
    58    * Open a new terminal window/tab. This terminal will be where we leave the UniK daemon running.
    59    * `cd` to the `_build` directory created by `make`
    60    * run `./unik daemon --debug` (the `--debug` flag is optional, if you want to see more verbose output)
    61    * UniK will compile and deploy its own 30 MB unikernel. This unikernel is the [Unik Instance Listener](./instance_listener.md). The instance listener uses udp broadcast to detect instance ips and bootstrap instances running on Virtualbox.
    62    * After this is finished, UniK is running and ready to accept commands.
    63    * Open a new terminal window and type `unik target --host localhost` to set the CLI target to the your local machine.
    64  
    65  ---
    66  
    67  #### Write a Java HTTP server using Maven
    68  0. Open a new terminal window, but leave the window with the daemon running. This window will be used for running UniK CLI commands.
    69  1. `mkdir` a new directory to create this sample app in & `cd` to it.
    70  2. Generate a new maven project with the following command:
    71  
    72    ```
    73    mvn -B archetype:generate \
    74      -DarchetypeGroupId=org.apache.maven.archetypes \
    75      -DgroupId=com.mycompany.app \
    76      -DartifactId=my-app
    77    ```
    78  
    79  Great! we've got the project structure created. Let's `cd` into the new project folder `my-app`.
    80  
    81  3. We need to add a plugin to our project's `pom.xml` so it can be built as a fat jar (all dependencies packaged into one `.jar` file):
    82    * Add the `maven-assembly-plugin` between the `<plugins>...</plugins>` tags:
    83  
    84  ```xml
    85  <plugins>
    86         <plugin>
    87            <groupId>org.apache.maven.plugins</groupId>
    88            <artifactId>maven-assembly-plugin</artifactId>
    89            <version>2.2-beta-4</version>
    90            <configuration>
    91              <descriptorRefs>
    92                <descriptorRef>jar-with-dependencies</descriptorRef>
    93              </descriptorRefs>
    94              <archive>
    95                <manifest>
    96                  <mainClass>com.mycompany.app.App</mainClass>
    97                </manifest>
    98              </archive>
    99            </configuration>
   100            <executions>
   101              <execution>
   102                <phase>package</phase>
   103                <goals>
   104                  <goal>single</goal>
   105                </goals>
   106              </execution>
   107            </executions>
   108         </plugin>
   109  </plugins>
   110  ```
   111  
   112    * Now our application is UniK-ready. Let's add some code to our `App.java` source file. Open up `src/main/java/com/mycompany/app/App.java` and replace its contents with the following:
   113  
   114  ```java
   115    package com.mycompany.app;
   116  
   117    import java.io.IOException;
   118    import java.io.OutputStream;
   119    import java.net.InetSocketAddress;
   120  
   121    import com.sun.net.httpserver.HttpExchange;
   122    import com.sun.net.httpserver.HttpHandler;
   123    import com.sun.net.httpserver.HttpServer;
   124  
   125    public class App
   126    {
   127      public static void main(String[] args) throws Exception {
   128          System.out.println("Started!");
   129          HttpServer server = HttpServer.create(new InetSocketAddress(4000), 0);
   130          server.createContext("/", new MyHandler());
   131          server.setExecutor(null); // creates a default executor
   132          server.start();
   133      }
   134  
   135      static class MyHandler implements HttpHandler {
   136          @Override
   137          public void handle(HttpExchange t) throws IOException {
   138              String response = "Java running inside a unikernel!";
   139              t.sendResponseHeaders(200, response.length());
   140              OutputStream os = t.getResponseBody();
   141              os.write(response.getBytes());
   142              os.close();
   143          }
   144      }
   145    }     
   146   ```
   147  
   148  2. If you have Java installed, you can try running this code with `mvn package && java -jar target/my-app-1.0-SNAPSHOT-jar-with-dependencies.jar`. Visit [http://localhost:4000/](http://localhost:4000/) to see that the server is running.
   149  
   150  3. We have to add a manifest file to tell unik how to build our application into a unikernel. Create a file named `manifest.yaml` in the same directory as the `pom.xml` (the java project root) and paste the following inside:
   151    
   152    ```yaml
   153    main_file: target/my-app-1.0-SNAPSHOT-jar-with-dependencies.jar
   154    build_command: mvn package
   155    ``` 
   156    This will tell UniK to build our project with the `mvn package` commmand, and that the resulting jar file will be located at `target/my-app-1.0-SNAPSHOT-jar-with-dependencies.jar`.
   157  
   158  4. Great! Now we're ready to compile this code to a unikernel.
   159  
   160  ---
   161  
   162  #### Compile an image and run on Virtualbox
   163  
   164  1. Make sure that the UniK daemon is still running, and run the following:
   165    ```
   166    unik build --name myJavaImage --path PATH_TO_JAVA_PROJECT --base osv --language java --provider virtualbox
   167    ```
   168    Replacing `PATH_TO_JAVA_PROJECT` with the path to the root of the java project we created. (This will be the directory containing the `pom.xml` file).
   169  2. You can watch the output of the `build` command in the terminal window running the daemon.
   170  3. When `build` finishes, the resulting disk image will exist as a virtual disk image in your `$HOME/.unik` directory.
   171  4. Run an instance of this image with
   172    ```
   173    unik run --instanceName myJavaInstance --imageName myJavaImage
   174    ```
   175  5. When the instance finishes launching, let's check its IP and see that it is running our application.
   176  6. Run `unik instances`. The instance IP Address should be listed.
   177  7. Direct your browser to `http://instance-ip:4000` and see that your instance is running!
   178  8. To clean up your image and the instance you created
   179    ```
   180    unik rmi --force --image myImage
   181    ```