1

I would like to understand is there a way to write a method to existing class at runtime and to create a jar dynamically in scala.

So far i tried to create a class dynamically and able to run it thru reflection, however the class is dynamic class which isnt generated.

val mirror = runtimeMirror(getClass.getClassLoader)
val tb = ToolBox(mirror).mkToolBox() 

val function = q"def function(x: Int): Int = x + 2"
    val functionWrapper = "object FunctionWrapper { " + function + "}"
data.map(x => tb.eval(q"$functionSymbol.function($x)"))

i got this from other source, however the class is available only for this run and will not be generated.

i would like to add a function to the existing class at runtime and able to compile it and create a jar for it.

Kindly suggest me the way

Thanks in advance.

8
  • 1
    This sounds like a terrible idea. Commented Aug 21, 2020 at 3:00
  • 1
    @LuisMiguelMejíaSuárez we will receive a string, based on it we need to add this as method to the class at runtime and need to generate a jar. so i started to first create a dynamic class, but not able to generate here. however i need to add the function to existing class. Commented Aug 21, 2020 at 3:03
  • 1
    We might actually receive an expression, based on the expression we need to create it a method for further use for spark udf creation. Commented Aug 21, 2020 at 3:12
  • 1
    So what could these expressions look like? It's usually better to come up with a restrictive language that allows users to express exactly what is needed and no more. This expression can then be compiled into a function object using a technique known as partial evaluation. Commented Aug 21, 2020 at 8:39
  • 1
    Someone with programming background will use the udf once the udfs are available. i would like to understand on how can we generate a class and bind it with jar dynamically. Commented Aug 21, 2020 at 15:05

1 Answer 1

3

I guess the code snippet you provided should actually look like

import scala.reflect.runtime.universe._
import scala.tools.reflect.ToolBox

val mirror = runtimeMirror(getClass.getClassLoader)
val tb = ToolBox(mirror).mkToolBox()

val function: Tree = q"def function(x: Int): Int = x + 2"
val functionWrapper: Symbol = tb.define(q"object FunctionWrapper { $function }".asInstanceOf[ImplDef])
val data: List[Tree] = List(q"1", q"2")
data.map(x => tb.eval(q"$functionWrapper.function($x)")) // List(3, 4)

... however the class is dynamic class which isnt generated.

... however the class is available only for this run and will not be generated.

How did you check that the class is not generated? (Which class, FunctionWrapper?)

is there a way to write a method to existing class at runtime and to create a jar dynamically in scala.

i would like to add a function to the existing class at runtime and able to compile it and create a jar for it.

What is "existing class"? Do you have access to its sources? Then you can modify the sources, compile them etc.

Does the class exist as a .class file? You can modify its byte code with Byte-buddy, ASM, Javassist, cglib etc., instrument the byte code with aspects etc.

Is it dynamic class (like FunctionWrapper above)? How did you create it? (For FunctionWrapper you have access to its Symbol so you can use it in further sources.)

Is the class already loaded? Then you'll have to play with class loaders (unload, modify, load modified).

Can a Java class add a method to itself at runtime?

In Java, given an object, is it possible to override one of the methods?

Sign up to request clarification or add additional context in comments.

8 Comments

Thanks for the info Dmytro.. 1. Yes, FunctionWrapper class isnt generated. 2. ok, will take a look on Byte-buddy
@user3569397 In what sense FunctionWrapper isn't generated? You have its symbol, you can use it in further sources. How do you check that it's not generated? What are you trying to do with FunctionWrapper that doesn't work for you?
@user3569397 If you create toolbox with ToolBox(mirror).mkToolBox(options = "-d /path/to/dir") then in dir you'll find .class file for FunctionWrapper. Without -d option it was created in a virtual directory in memory.
Hi Dmytro, apologies if am not explaining it correctly. i tried checking in source packages. May i please request you where can i check the class created?
@user3569397 It's not in src/main/scala..., it's in dir that you specify with -d key in options parameter of mkToolBox, otherwise it's in memory (by default). github.com/scala/scala/blob/2.13.x/src/compiler/scala/tools/…
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.