title: CorDapp is working in CRaSH Shell but API is not recognizing CorDapp
body: <p>I'm trying to expose an API for a CorDapp and the functions are not displaying. When looking at an example (<a href="https://github.com/roger3cev/obligation-cordapp" rel="nofollow noreferrer">https://github.com/roger3cev/obligation-cordapp</a>), I receive the following page: <a href="https://imgur.com/a/ifOdrAd" rel="nofollow noreferrer">https://imgur.com/a/ifOdrAd</a>, however when I load my CorDapp, it says there are no installed Cordapps and /api on the localhost returns a 404. In the project, I feel the problem lies somewhere here: <a href="https://github.com/PronoyC/InsureFlight/tree/master/cordapp/src/main/kotlin/com/insureflight" rel="nofollow noreferrer">https://github.com/PronoyC/InsureFlight/tree/master/cordapp/src/main/kotlin/com/insureflight</a>. I know this is very vague but I cannot find any errors that indicate a specific area. Any help would be appreciated.</p>
  
  <p>InsureFlightApi.kt:</p>
  
  <pre><code>package com.insureflight
  
  import net.corda.core.contracts.Amount
  import net.corda.core.contracts.UniqueIdentifier
  import net.corda.core.messaging.CordaRPCOps
  import net.corda.core.utilities.OpaqueBytes
  import net.corda.core.utilities.getOrThrow
  import com.insureflight.flows.IssuePolicy
  import com.insureflight.flows.PayoutPolicy
  import net.corda.finance.contracts.asset.Cash
  import net.corda.finance.contracts.getCashBalances
  import net.corda.finance.flows.CashIssueFlow
  import java.util.*
  import javax.ws.rs.GET
  import javax.ws.rs.Path
  import javax.ws.rs.Produces
  import javax.ws.rs.QueryParam
  import javax.ws.rs.core.MediaType
  import javax.ws.rs.core.Response
  import javax.ws.rs.core.Response.Status.BAD_REQUEST
  import javax.ws.rs.core.Response.Status.CREATED
  
  @Path("insureflight")
  class InsureFlightApi(val rpcOps: CordaRPCOps) {
  
  private val myIdentity = rpcOps.nodeInfo().legalIdentities.first()
  
  @GET
  @Path("me")
  @Produces(MediaType.APPLICATION_JSON)
  fun me() = mapOf("me" to myIdentity)
  
  @GET
  @Path("peers")
  @Produces(MediaType.APPLICATION_JSON)
  fun peers() = mapOf("peers" to rpcOps.networkMapSnapshot()
          .filter { nodeInfo -&gt; nodeInfo.legalIdentities.first() != myIdentity }
          .map { it.legalIdentities.first().name.organisation })
  
  @GET
  @Path("policies")
  @Produces(MediaType.APPLICATION_JSON)
  fun policies() = rpcOps.vaultQuery(Policy::class.java).states
  
  @GET
  @Path("cash")
  @Produces(MediaType.APPLICATION_JSON)
  fun cash() = rpcOps.vaultQuery(Cash.State::class.java).states
  
  @GET
  @Path("cash-balances")
  @Produces(MediaType.APPLICATION_JSON)
  fun getCashBalances() = rpcOps.getCashBalances()
  
  @GET
  @Path("self-issue-cash")
  fun selfIssueCash(@QueryParam(value = "amount") amount: Int,
                    @QueryParam(value = "currency") currency: String): Response {
  
      // 1. Prepare issue request.
      val issueAmount = Amount(amount.toLong(), Currency.getInstance(currency))
      val notary = rpcOps.notaryIdentities().firstOrNull() ?: throw IllegalStateException("Could not find a notary.")
      val issueRef = OpaqueBytes.of(0)
      val issueRequest = CashIssueFlow.IssueRequest(issueAmount, issueRef, notary)
  
      // 2. Start flow and wait for response.
      val (status, message) = try {
          val flowHandle = rpcOps.startFlowDynamic(CashIssueFlow::class.java, issueRequest)
          val result = flowHandle.use { it.returnValue.getOrThrow() }
          CREATED to result.stx.tx.outputs.single().data
      } catch (e: Exception) {
          BAD_REQUEST to e.message
      }
  
      // 3. Return the response.
      return Response.status(status).entity(message).build()
  }
  
  @GET
  @Path("issue-policy")
  fun issuePolicy(@QueryParam(value = "premium") premium: Int,
                  @QueryParam(value = "currency") currency: String,
                  @QueryParam(value = "client") client: String,
                  @QueryParam(value = "underwriter") underwriter: String,
                  @QueryParam(value = "flight") flight: String,
                  @QueryParam(value = "fStatus") fStatus: String): Response {
  
      // 1. Create a premium object.
      val issuePremium = Amount(premium.toLong() * 100, Currency.getInstance(currency))
  
      // 2. Start the IssuePolicy flow. We block and wait for the flow to return.
      val (status, message) = try {
          val flowHandle = rpcOps.startFlowDynamic(
                  IssuePolicy.Initiator::class.java,
                  issuePremium,
                  client,
                  underwriter,
                  flight,
                  fStatus,
                  true
          )
  
          val result = flowHandle.use { it.returnValue.getOrThrow() }
          CREATED to "Transaction id ${result.id} committed to ledger.\n${result.tx.outputs.single().data}"
      } catch (e: Exception) {
          BAD_REQUEST to e.message
      }
  
      // 3. Return the result.
      return Response.status(status).entity(message).build()
  }
  
  @GET
  @Path("payout-policy")
  fun settlePolicy(@QueryParam(value = "id") id: String,
                   @QueryParam(value = "delayedMinutes") delayedMinutes: Int,
                   @QueryParam(value = "fStatus") fStatus: String): Response {
      // 1. Get party objects for the counterparty.
      val linearId = UniqueIdentifier.fromString(id)
  
      // 2. Start the SettlePolicy flow. We block and wait for the flow to return.
      val (status, message) = try {
          val flowHandle = rpcOps.startFlowDynamic(
                  PayoutPolicy.Initiator::class.java,
                  linearId,
                  delayedMinutes,
                  fStatus,
                  true
          )
  
          flowHandle.use { flowHandle.returnValue.getOrThrow() }
          CREATED to "Policy $linearId has been settled."
      } catch (e: Exception) {
          BAD_REQUEST to e.message
      }
  
      // 3. Return the result.
      return Response.status(status).entity(message).build()
  }
  }
  </code></pre>
  
  <p>InsureFlightPlugin.kt (ObligationPlugin.kt is very similar to this):</p>
  
  <pre><code>package com.insureflight
  
  import net.corda.core.messaging.CordaRPCOps
  import net.corda.webserver.services.WebServerPluginRegistry
  import java.util.function.Function
  
  class InsureFlightPlugin : WebServerPluginRegistry {
  override val webApis: List&lt;Function&lt;CordaRPCOps, out Any&gt;&gt; = listOf(Function(::InsureFlightApi))
  override val staticServeDirs: Map&lt;String, String&gt; = mapOf(
          "policy" to javaClass.classLoader.getResource("policyWeb").toExternalForm()
  )
  }
  </code></pre>