I want to create a class at run-time in Scala. For now, just consider a simple case where I want to make the equivalent of a java bean with some attributes, I only know these attributes at run time.
How can I create the scala class? I am willing to create from scala source file if there is a way to compile it and load it at run time, I may want to as I sometimes have some complex function I want to add to the class. How can I do it?
I worry that the scala interpreter which I read about is sandboxing the interpreted code that it loads so that it won't be available to the general application hosting the interpreter? If this is the case, then I wouldn't be able to use the dynamically loaded scala class.
Anyway, the question is, how can I dynamically create a scala class at run time and use it in my application, best case is to load it from a scala source file at run time, something like interpreterSource("file.scala") and its loaded into my current runtime, second best case is some creation by calling methods ie. createClass(...) to create it at runtime.
Thanks, Phil
There's not enough information to know the best answer, but do remember that you're running on the JVM, so any techniques or bytecode engineering libraries valid for Java should also be valid here.
There are hundreds of techniques you might use, but the best choice depends totally on your exact use case, as many aren't general purpose. Here's a couple of ideas though:
For a simple bean, you may as well
just use a map, or look into the
DynaBean class from apache commons.
For more advanced behaviour you could
invoke the compiler explicitly and
then grab the resulting .class file
via a classloader (this is largely
how JSPs do it)
A parser and custom DSL fit well in
some cases. As does bean shell
scripting.
Check out the ScalaDays video here: http://days2010.scala-lang.org/node/138/146
which demonstrates the use of Scala as a JSR-223 compliant scripting language.
This should cover most scenarios where you'd want to evaluate Scala at runtime.
You'll also want to look at the email thread here: http://scala-programming-language.1934581.n4.nabble.com/Compiler-API-td1992165.html#a1992165
This contains the following sample code:
// We currently call the compiler directly
// To reduce coupling, we could instead use ant and the scalac ant task
import scala.tools.nsc.{Global, Settings}
import scala.tools.nsc.reporters.ConsoleReporter
{
// called in the event of a compilation error
def error(message: String): Nothing = ...
val settings = new Settings(error)
settings.outdir.value = classesDir.getPath
settings.deprecation.value = true // enable detailed deprecation warnings
settings.unchecked.value = true // enable detailed unchecked warnings
val reporter = new ConsoleReporter(settings)
val compiler = new Global(settings, reporter)
(new compiler.Run).compile(filenames)
reporter.printSummary
if (reporter.hasErrors || reporter.WARNING.count > 0)
{
...
}
}
val mainMethod: Method = {
val urls = Array[URL]( classesDir.toURL )
val loader = new URLClassLoader(urls)
try {
val clazz: Class = loader.loadClass(...)
val method: Method = clazz.getMethod("main", Array[Class]( classOf[Array[String]] ))
if (Modifier.isStatic(method.getModifiers)) {
method
} else {
...
}
} catch {
case cnf: ClassNotFoundException => ...
case nsm: NoSuchMethodException => ...
}
}
mainMethod.invoke(null, Array[Object]( args ))
Related
I have a factory that should return an implementation depending on the name.
val moduleMap = Map(Modules.moduleName -> new ModuleImpl)
def getModule(moduleName: String): Module =
moduleMap.get(moduleName) match {
case Some(m) => m
case _ =>
throw new ModuleNotFoundException(
s"$moduleName - Module could not be found.")
}
In order for each call to the "getModule" method not to create an instance, there is a map in which all the modules must be initialized in bootstrap class.
I would like to get rid of the need to do this manually(also all classes have a distinctive feature).
List of options that came to my mind:
Reflection(we can use Scala Reflection API or any thrid-party
library)
Automated process.
Need to initialize immediately at startup.
Reflection is a pain.
Metaprogramming(ScalaMeta) + Reflection
Macros only change the code, the execution happens later.
Can we move initialization process to compile time?
I know that compiler can optimize and replace code, next fragment before compilation
val a = 5 + 5
after compilation compiler change that piece to 10, can we use some directives or another tools to evaluate and execute some code at compile time and use only final value?
Do you use any framework or you write your own? I answered similar question about Guice here. You can use it without Guice as well: instead of Module you will have your Factory, which you need to initialize from somewhere, and during initialization, you will fill your map using reflection
In general I think it is the easiest approach. Alternatively, you can write macros, which just replaces part of reflective initialization, but not sure that it will give you some profit (if I understand your question right, this initialization will happen just once at startup).
I do not see how scalameta can help you? Probably, only in case if all your implementations are in source tree available to you, so you can analyze it and generate initialization (similar to macros)? Probably, this would add such plus as easier search for implementation, but will add minus: will work only on implementations in your sources.
Your example of compile-time optimization is not applicable. In your example, you talk about compile-time constant (even with arithmetic it could be a problem, see this comment), but in your question you need specific run-time behavior. So compile time could be only code generation from macros or based on scalameta from my point of view.
I'm currently working with reasonably large code base where new code is written in scala, but where a lot of old Java code remains. In particular there are a lot of java APIs we have to talk to. The old code uses simple Java Pojos with public non-final fields, without any methods or constructors, e.g:
public class MyJavaPojo {
public String myField1;
public MyOtheJavaPojo myField2;
}
Note that we dont have the option of adding helper methods or constructors to these types. These are currently created like old c-structs (pre-named parameters) like this:
val myPojo = new MyJavaPojo
myPojo.myField1 = ...
myPojo.myField2 = ...
Because of this, it's very easy to forget about assigning one of the fields, especially when we suddenly add new fields to the MyJavaPojo class, the compiler wont complain that I've left one field to null.
NOTE: We don't have the option of modifying the java types/adding constructors the normal way. We also don't want to start creating lots and lots of manually created helper functions for object creation - We would really like to find a solution based on scala macros instead of possible!
What I would like to do would be to create a macro that generates either a constructor-like method for my Pojos or a macro that creates a factory, allowing for named parameters. (Basically letting a macro do the work instead of creating a gazillion manually written helper methods in scala).
Do you know of any way to do this with scala macros? (I'm certain it's possible, but I've never written a scala macro in my life)
Desired API alternative 1:
val myPojo = someMacro[MyJavaPojo](myField1 = ..., myField2 = ...)
Desired API alternative 2
val factory = someMacro[MyJavaPojo]
val myPojo = factory.apply(myField1 = ..., myField2 = ...)
NOTE/Important: Named parameters!
I'm looking for either a ready-to-use solution or hints as to where I can read up on making one.
All ideas and input appreciated!
Take a look at scala-beanutils.
#beanCompanion[MyJavaPojo] object MyScalaPojo
MyScalaPojo(...)
It probably won't work directly, as you classes are not beans and it's only been made for Scala 2.10, but the source code is < 200 lines and should give you an idea of where to start.
I am reading online about cross cutting concerns since I just implemented Log4j into my code. Some people are saying using AspectJ is okay, while others point out that it breaks functional programming. That mixins are Scala's solution for cross cutting concerns.
However, I cringe when I think I will extend a trait to an object/ class that is not related itself.
e.g. new Database with Logger
Here Logger has nothing to do with Database, but its how to mixing to provide logging. I would prefer to do it the Scala way, so I want to find out this is what people mean by mixins.
Can someone please show me a quick example of how to go about this in Scala?
This is a big topic with lots of potential "correct" answers. My personal favourite would be using either "by name parameters" or higher order functions.
A a very simple example of this:
object Logging {
def logCall[T](name: String)(block: => T): T = {
log.info(s"Invoking: $name")
block
}
}
Which would allow you to apply it both in an object that itself knows about the cross cutting concern (something like annotating wrapping a method call with something in java):
class DB {
import Logging._
def insert(item: Something) = logCall("insert") {
???
}
}
Or at the call site:
import Logging._
def businessLogic() {
val user = ???
val result = logCall("insert user")(DB.insert(user))
println(result)
}
The nice thing with this is that it is very explicit and self explanatory (which, again, are things you might value high or not).
When working with dependency resolution in gradle, you usually see something like this:
configurations {
optional
compile
runtime.extendsFrom compile
testCompile.extendsFrom runtime
}
and I wanted to know of what type is optional or compile? Is it a Class? a string? what methods can I call for it?
Besides all this, is there a way to find out these things automatically, similar to ctrl+space when on something in eclipse?
They are classes that implements org.gradle.api.artifacts.Configuration. The Gradle DSL doc also contains more information about the configuration DSL core type.
To find out more info about internal classes etc, which is useful when for instance looking up classes and methods in the Gradle javadoc, it is often as simple as just printing out the class names. Quite often though, you will end up with some internal implementing class instead of the API interface you're interested in, but regardless of that it's a way get started on what to search for. I tend to keep the source code of all open source projects we're using available in the IDE. That way it's easy to jump into the correct class (even when it's not available through context shortcuts) and look around.
To get more information about configurations in your case, you could add a task that simply prints out the relevant info. E.g. something like:
task configInfo << {
println "configurations.class: ${configurations.class}"
println "configurations.compile class: ${configurations.compile.class}"
println "implements ${Configuration} interface? ${configurations.compile instanceof Configuration}"
}
which in my case results in the following output
$ gradle configInfo
:configInfo
configurations.class: class org.gradle.api.internal.artifacts.configurations.DefaultConfigurationContainer_Decorated
configurations.compile class: class org.gradle.api.internal.artifacts.configurations.DefaultConfiguration_Decorated
implements interface org.gradle.api.artifacts.Configuration interface? true
I am no Gradle expert, but this seems like a simple getter delegated to another object in a DSL fashion. You could write the same with something like this:
class MyDsl {
def config = [:].withDefault { false }
void configure(closure) {
closure.delegate = this
closure()
}
def getOptional() { config.optional = true }
def getCompile() { config.compile = true }
def getTest() { config.test = true }
}
dsl = new MyDsl()
dsl.configure {
optional
compile
}
dsl.config.with {
assert optional
assert compile
assert !test
}
You could return some specific object to pass to runtime.extendsFrom() method.
For auto-complete, IIRC that's what groovy-eclipse DSLD (DSL descriptors) are for. You may want to give a try to this gradle DSLD which is in eclipse-integration-gradle plugin.
As per this ticket it has been done long ago.
The question "what type is optional or compile" isn't really valid. That is kind of like asking what type does "instanceof" have. The instanceof keywword doesn't have a type.
When writing code like you cited, you are taking advantage of a DSL. Treat words like compile and optional as keywords in that DSL. Unless you are writing your own DSL (as opposed to taking advantage of existing one, which is what this question is about), don't think of types being associated with those things.
As for the question about ctrl+space, Eclipse won't do anything special with that in this context unless you are using a plugin which provides support for that. Even with plugin support there will still be limitations because you can define your own configurations. If you were going to define a configuration named "jeffrey" and you typed "jeff" followed by ctrl+space, there is no way for the IDE to know you want it to turn that into "jeffrey".
I hope that helps.
I just read and enjoyed the Cake pattern article. However, to my mind, one of the key reasons to use dependency injection is that you can vary the components being used by either an XML file or command-line arguments.
How is that aspect of DI handled with the Cake pattern? The examples I've seen all involve mixing traits in statically.
Since mixing in traits is done statically in Scala, if you want to vary the traits mixed in to an object, create different objects based on some condition.
Let's take a canonical cake pattern example. Your modules are defined as traits, and your application is constructed as a simple Object with a bunch of functionality mixed in
val application =
new Object
extends Communications
with Parsing
with Persistence
with Logging
with ProductionDataSource
application.startup
Now all of those modules have nice self-type declarations which define their inter-module dependencies, so that line only compiles if your all inter-module dependencies exist, are unique, and well-typed. In particular, the Persistence module has a self-type which says that anything implementing Persistence must also implement DataSource, an abstract module trait. Since ProductionDataSource inherits from DataSource, everything's great, and that application construction line compiles.
But what if you want to use a different DataSource, pointing at some local database for testing purposes? Assume further that you can't just reuse ProductionDataSource with different configuration parameters, loaded from some properties file. What you would do in that case is define a new trait TestDataSource which extends DataSource, and mix it in instead. You could even do so dynamically based on a command line flag.
val application = if (test)
new Object
extends Communications
with Parsing
with Persistence
with Logging
with TestDataSource
else
new Object
extends Communications
with Parsing
with Persistence
with Logging
with ProductionDataSource
application.startup
Now that looks a bit more verbose than we would like, particularly if your application needs to vary its construction on multiple axes. On the plus side, you usually you only have one chunk of conditional construction logic like that in an application (or at worst once per identifiable component lifecycle), so at least the pain is minimized and fenced off from the rest of your logic.
Scala is also a script language. So your configuration XML can be a Scala script. It is type-safe and not-a-different-language.
Simply look at startup:
scala -cp first.jar:second.jar startupScript.scala
is not so different than:
java -cp first.jar:second.jar com.example.MyMainClass context.xml
You can always use DI, but you have one more tool.
The short answer is that Scala doesn't currently have any built-in support for dynamic mixins.
I am working on the autoproxy-plugin to support this, although it's currently on hold until the 2.9 release, when the compiler will have new features making it a much easier task.
In the meantime, the best way to achieve almost exactly the same functionality is by implementing your dynamically added behavior as a wrapper class, then adding an implicit conversion back to the wrapped member.
Until the AutoProxy plugin becomes available, one way to achieve the effect is to use delegation:
trait Module {
def foo: Int
}
trait DelegatedModule extends Module {
var delegate: Module = _
def foo = delegate.foo
}
class Impl extends Module {
def foo = 1
}
// later
val composed: Module with ... with ... = new DelegatedModule with ... with ...
composed.delegate = choose() // choose is linear in the number of `Module` implementations
But beware, the downside of this is that it's more verbose, and you have to be careful about the initialization order if you use vars inside a trait. Another downside is that if there are path dependent types within Module above, you won't be able to use delegation that easily.
But if there is a large number of different implementations that can be varied, it will probably cost you less code than listing cases with all possible combinations.
Lift has something along those lines built in. It's mostly in scala code, but you have some runtime control. http://www.assembla.com/wiki/show/liftweb/Dependency_Injection