I am struggling with how to dynamically add some webservices. I am using Scalatra for the webservice framework.
I want to allow the developer to be able to change authentication, for example, so that rather than using hard-coded credentials, instead use a database or password file or whatever they need.
I also want to allow them to add new webservices inside the servlet.
So, what I want to do is in the bootstrap code have it load up and recompile the class and then use that version.
I have looked at this, but I need to recompile an entire class, not snippets.
Generating a class from string and instantiating it in Scala 2.10
This is what I have tried, but I added a "/help" webservice but it isn't found, so the new class isn't being used yet.
class ScalatraBootstrap extends LifeCycle {
override def init(context: ServletContext) {
val sourceDir = new java.io.File("C:/Temp/MyServlet.scala")
val sse = ScalaScriptEngine.onChangeRefresh(sourceDir)
sse.refresh
println("*** - " + sse.compilationStatus.startTime + " " + sse.compilationStatus.stopTime)
context.mount(sse.get[MyServlet]("test.proj.MyServlet"), "/*")
I am using scalascriptengine (https://code.google.com/p/scalascriptengine/) at the moment.
So, how can I recompile the class file for the webservice, when it may have case classes, annotations and object classes in the same file, on the fly?
I am wondering if I need to have the webservice in Groovy instead, but I would prefer to keep it functional.
UPDATE
I had thought about plugins first, but ran into a problem with how would I add new webservices that way, and it may be that Scalatra is not going to be the right choice, that I may need to change my REST service framework.
Eventually I want to be able to change the webservices on the fly without having to restart the application, and recompiling the source would allow that.
Realizing a plug-in affordance is not too hard, at least for reasonably simple cases. The essential elements are:
java.lang.Class[P <: PlugInType]
it's trivial to get an instance, provided you don't need constructor parameters.