This page is no longer maintained — Please continue to the home page at www.scala-lang.org

Joy of Reflection

14 replies
kolotyluk
Joined: 2010-06-04,
User offline. Last seen 5 weeks 15 hours ago.

I've been trying to get some simple reflection working but cannot seem
to figure it out. The code I am using from
http://stackoverflow.com/questions/1469958/scala-how-do-i-dynamically-in...
looks like

val mainClass =
Class.forName("com.kodak.intersystem.scripts.Intersystem").newInstance.asInstanceOf[{
def main(arguments : Array[String]) }]
mainClass.main(arguments)

but when it runs I get (see below) which does not mean very much.
Basically I am just trying to invoke the main method of another class in
the standard fashion.

java.lang.InstantiationException: com.kodak.intersystem.scripts.Intersystem
at java.lang.Class.newInstance0(Class.java:340)
at java.lang.Class.newInstance(Class.java:308)
at Main$.main(Compile.scala:89)
at Main.main(Compile.scala)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at
sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at
scala.tools.nsc.util.ScalaClassLoader$$anonfun$run$1.apply(ScalaClassLoader.scala:78)
at
scala.tools.nsc.util.ScalaClassLoader$class.asContext(ScalaClassLoader.scala:24)
at
scala.tools.nsc.util.ScalaClassLoader$URLClassLoader.asContext(ScalaClassLoader.scala:88)
at
scala.tools.nsc.util.ScalaClassLoader$class.run(ScalaClassLoader.scala:78)
at
scala.tools.nsc.util.ScalaClassLoader$URLClassLoader.run(ScalaClassLoader.scala:101)
at scala.tools.nsc.ObjectRunner$.run(ObjectRunner.scala:33)
at scala.tools.nsc.ObjectRunner$.runAndCatch(ObjectRunner.scala:40)
at
scala.tools.nsc.ScriptRunner.scala$tools$nsc$ScriptRunner$$runCompiled(ScriptRunner.scala:171)
at
scala.tools.nsc.ScriptRunner$$anonfun$runScript$1.apply(ScriptRunner.scala:188)
at
scala.tools.nsc.ScriptRunner$$anonfun$runScript$1.apply(ScriptRunner.scala:188)
at
scala.tools.nsc.ScriptRunner$$anonfun$withCompiledScript$1.apply$mcZ$sp(ScriptRunner.scala:157)
at
scala.tools.nsc.ScriptRunner$$anonfun$withCompiledScript$1.apply(ScriptRunner.scala:131)
at
scala.tools.nsc.ScriptRunner$$anonfun$withCompiledScript$1.apply(ScriptRunner.scala:131)
at
scala.tools.nsc.util.package$.waitingForThreads(package.scala:26)
at
scala.tools.nsc.ScriptRunner.withCompiledScript(ScriptRunner.scala:130)
at scala.tools.nsc.ScriptRunner.runScript(ScriptRunner.scala:188)
at
scala.tools.nsc.ScriptRunner.runScriptAndCatch(ScriptRunner.scala:201)
at
scala.tools.nsc.MainGenericRunner.runTarget$1(MainGenericRunner.scala:58)
at
scala.tools.nsc.MainGenericRunner.process(MainGenericRunner.scala:80)
at
scala.tools.nsc.MainGenericRunner$.main(MainGenericRunner.scala:89)
at scala.tools.nsc.MainGenericRunner.main(MainGenericRunner.scala)

If I run the following code

Class.forName("com.kodak.intersystem.scripts.Intersystem").getMethods.foreach(println(_))

I get

public static final void
com.kodak.intersystem.scripts.Intersystem.main(java.lang.String[])
public static final boolean com.kodak.intersystem.scripts.Intersystem.exit()
public static final com.kodak.intersystem.common.Properties
com.kodak.intersystem.scripts.Intersystem.properties()
public static final void
com.kodak.intersystem.scripts.Intersystem.getEnv(java.lang.String)
public static final void
com.kodak.intersystem.scripts.Intersystem.SCALA_HOME()
public static final void
com.kodak.intersystem.scripts.Intersystem.scalaBat_$eq(java.lang.String)
public static final java.lang.String
com.kodak.intersystem.scripts.Intersystem.scalaBat()
public static final void
com.kodak.intersystem.scripts.Intersystem.exit_$eq(boolean)
public static final org.slf4j.Logger
com.kodak.intersystem.scripts.Intersystem.logger()
public static final void
com.kodak.intersystem.scripts.Intersystem.POSTGRES_HOME()
public static final void
com.kodak.intersystem.scripts.Intersystem.emitWarn(java.lang.String)
public static final void
com.kodak.intersystem.scripts.Intersystem.emitError(java.lang.String)
public static final void
com.kodak.intersystem.scripts.Intersystem.emitInfo(java.lang.String)
public static final void
com.kodak.intersystem.scripts.Intersystem.emit(java.lang.String)
public static final java.lang.Class
com.kodak.intersystem.scripts.Intersystem.string2Class(java.lang.String,java.lang.ClassLoader)
public static final void
com.kodak.intersystem.scripts.Intersystem.pg_dumpExe_$eq(java.lang.String)
public static final java.lang.String
com.kodak.intersystem.scripts.Intersystem.pg_dumpExe()
public final native void java.lang.Object.wait(long) throws
java.lang.InterruptedException
public final void java.lang.Object.wait() throws
java.lang.InterruptedException
public final void java.lang.Object.wait(long,int) throws
java.lang.InterruptedException
public boolean java.lang.Object.equals(java.lang.Object)
public java.lang.String java.lang.Object.toString()
public native int java.lang.Object.hashCode()
public final native java.lang.Class java.lang.Object.getClass()
public final native void java.lang.Object.notify()
public final native void java.lang.Object.notifyAll()

so I cannot figure out why the Scala reflection API is having trouble
with invoking my main method.

Cheers, Eric

Ryan Richt
Joined: 2011-05-02,
User offline. Last seen 42 years 45 weeks ago.
Re: Joy of Reflection

Dear Eric,

Does the class in question have a no-arg constructor? When you call ".newInstance" I believe it tries to invoke (only) the no-arg constructor. If you don't have one, you will get an InstantiationException.

Ryan Richt
Monsanto

On Jan 23, 2012, at 5:22 PM, Eric Kolotyluk wrote:

> I've been trying to get some simple reflection working but cannot seem to figure it out. The code I am using from http://stackoverflow.com/questions/1469958/scala-how-do-i-dynamically-in... looks like
>
> val mainClass = Class.forName("com.kodak.intersystem.scripts.Intersystem").newInstance.asInstanceOf[{ def main(arguments : Array[String]) }]
> mainClass.main(arguments)
>
> but when it runs I get (see below) which does not mean very much. Basically I am just trying to invoke the main method of another class in the standard fashion.
>
> java.lang.InstantiationException: com.kodak.intersystem.scripts.Intersystem
> at java.lang.Class.newInstance0(Class.java:340)
> at java.lang.Class.newInstance(Class.java:308)
> at Main$.main(Compile.scala:89)
> at Main.main(Compile.scala)
> at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
> at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
> at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
> at java.lang.reflect.Method.invoke(Method.java:597)
> at scala.tools.nsc.util.ScalaClassLoader$$anonfun$run$1.apply(ScalaClassLoader.scala:78)
> at scala.tools.nsc.util.ScalaClassLoader$class.asContext(ScalaClassLoader.scala:24)
> at scala.tools.nsc.util.ScalaClassLoader$URLClassLoader.asContext(ScalaClassLoader.scala:88)
> at scala.tools.nsc.util.ScalaClassLoader$class.run(ScalaClassLoader.scala:78)
> at scala.tools.nsc.util.ScalaClassLoader$URLClassLoader.run(ScalaClassLoader.scala:101)
> at scala.tools.nsc.ObjectRunner$.run(ObjectRunner.scala:33)
> at scala.tools.nsc.ObjectRunner$.runAndCatch(ObjectRunner.scala:40)
> at scala.tools.nsc.ScriptRunner.scala$tools$nsc$ScriptRunner$$runCompiled(ScriptRunner.scala:171)
> at scala.tools.nsc.ScriptRunner$$anonfun$runScript$1.apply(ScriptRunner.scala:188)
> at scala.tools.nsc.ScriptRunner$$anonfun$runScript$1.apply(ScriptRunner.scala:188)
> at scala.tools.nsc.ScriptRunner$$anonfun$withCompiledScript$1.apply$mcZ$sp(ScriptRunner.scala:157)
> at scala.tools.nsc.ScriptRunner$$anonfun$withCompiledScript$1.apply(ScriptRunner.scala:131)
> at scala.tools.nsc.ScriptRunner$$anonfun$withCompiledScript$1.apply(ScriptRunner.scala:131)
> at scala.tools.nsc.util.package$.waitingForThreads(package.scala:26)
> at scala.tools.nsc.ScriptRunner.withCompiledScript(ScriptRunner.scala:130)
> at scala.tools.nsc.ScriptRunner.runScript(ScriptRunner.scala:188)
> at scala.tools.nsc.ScriptRunner.runScriptAndCatch(ScriptRunner.scala:201)
> at scala.tools.nsc.MainGenericRunner.runTarget$1(MainGenericRunner.scala:58)
> at scala.tools.nsc.MainGenericRunner.process(MainGenericRunner.scala:80)
> at scala.tools.nsc.MainGenericRunner$.main(MainGenericRunner.scala:89)
> at scala.tools.nsc.MainGenericRunner.main(MainGenericRunner.scala)
>
> If I run the following code
>
> Class.forName("com.kodak.intersystem.scripts.Intersystem").getMethods.foreach(println(_))
>
> I get
>
> public static final void com.kodak.intersystem.scripts.Intersystem.main(java.lang.String[])
> public static final boolean com.kodak.intersystem.scripts.Intersystem.exit()
> public static final com.kodak.intersystem.common.Properties com.kodak.intersystem.scripts.Intersystem.properties()
> public static final void com.kodak.intersystem.scripts.Intersystem.getEnv(java.lang.String)
> public static final void com.kodak.intersystem.scripts.Intersystem.SCALA_HOME()
> public static final void com.kodak.intersystem.scripts.Intersystem.scalaBat_$eq(java.lang.String)
> public static final java.lang.String com.kodak.intersystem.scripts.Intersystem.scalaBat()
> public static final void com.kodak.intersystem.scripts.Intersystem.exit_$eq(boolean)
> public static final org.slf4j.Logger com.kodak.intersystem.scripts.Intersystem.logger()
> public static final void com.kodak.intersystem.scripts.Intersystem.POSTGRES_HOME()
> public static final void com.kodak.intersystem.scripts.Intersystem.emitWarn(java.lang.String)
> public static final void com.kodak.intersystem.scripts.Intersystem.emitError(java.lang.String)
> public static final void com.kodak.intersystem.scripts.Intersystem.emitInfo(java.lang.String)
> public static final void com.kodak.intersystem.scripts.Intersystem.emit(java.lang.String)
> public static final java.lang.Class com.kodak.intersystem.scripts.Intersystem.string2Class(java.lang.String,java.lang.ClassLoader)
> public static final void com.kodak.intersystem.scripts.Intersystem.pg_dumpExe_$eq(java.lang.String)
> public static final java.lang.String com.kodak.intersystem.scripts.Intersystem.pg_dumpExe()
> public final native void java.lang.Object.wait(long) throws java.lang.InterruptedException
> public final void java.lang.Object.wait() throws java.lang.InterruptedException
> public final void java.lang.Object.wait(long,int) throws java.lang.InterruptedException
> public boolean java.lang.Object.equals(java.lang.Object)
> public java.lang.String java.lang.Object.toString()
> public native int java.lang.Object.hashCode()
> public final native java.lang.Class java.lang.Object.getClass()
> public final native void java.lang.Object.notify()
> public final native void java.lang.Object.notifyAll()
>
> so I cannot figure out why the Scala reflection API is having trouble with invoking my main method.
>
> Cheers, Eric

This e-mail message may contain privileged and/or confidential information, and is intended to be received only by persons entitled
to receive such information. If you have received this e-mail in error, please notify the sender immediately. Please delete it and
all attachments from any servers, hard drives or any other media. Other use of this e-mail by you is strictly prohibited.

All e-mails and attachments sent and received are subject to monitoring, reading and archival by Monsanto, including its
subsidiaries. The recipient of this e-mail is solely responsible for checking for the presence of "Viruses" or other "Malware".
Monsanto, along with its subsidiaries, accepts no liability for any damage caused by any such code transmitted by or accompanying
this e-mail or any attachment.

The information contained in this email may be subject to the export control laws and regulations of the United States, potentially
including but not limited to the Export Administration Regulations (EAR) and sanctions regulations issued by the U.S. Department of
Treasury, Office of Foreign Asset Controls (OFAC). As a recipient of this information you are obligated to comply with all
applicable U.S. export laws and regulations.

kolotyluk
Joined: 2010-06-04,
User offline. Last seen 5 weeks 15 hours ago.
Re: Joy of Reflection

The class is defined as

object Intersystem extends Emitter {
...

Does that create a no-arg constructor? I just assumed it did.

Cheers, Eric

On 2012-01-23 4:43 PM, RICHT, RYAN JERRY (AG/1005) wrote:
> Dear Eric,
>
> Does the class in question have a no-arg constructor? When you call ".newInstance" I believe it tries to invoke (only) the no-arg constructor. If you don't have one, you will get an InstantiationException.
>
> Ryan Richt
> Monsanto
>
>
> On Jan 23, 2012, at 5:22 PM, Eric Kolotyluk wrote:
>
>> I've been trying to get some simple reflection working but cannot seem to figure it out. The code I am using from http://stackoverflow.com/questions/1469958/scala-how-do-i-dynamically-in... looks like
>>
>> val mainClass = Class.forName("com.kodak.intersystem.scripts.Intersystem").newInstance.asInstanceOf[{ def main(arguments : Array[String]) }]
>> mainClass.main(arguments)
>>
>> but when it runs I get (see below) which does not mean very much. Basically I am just trying to invoke the main method of another class in the standard fashion.
>>
>> java.lang.InstantiationException: com.kodak.intersystem.scripts.Intersystem
>> at java.lang.Class.newInstance0(Class.java:340)
>> at java.lang.Class.newInstance(Class.java:308)
>> at Main$.main(Compile.scala:89)
>> at Main.main(Compile.scala)
>> at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
>> at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
>> at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
>> at java.lang.reflect.Method.invoke(Method.java:597)
>> at scala.tools.nsc.util.ScalaClassLoader$$anonfun$run$1.apply(ScalaClassLoader.scala:78)
>> at scala.tools.nsc.util.ScalaClassLoader$class.asContext(ScalaClassLoader.scala:24)
>> at scala.tools.nsc.util.ScalaClassLoader$URLClassLoader.asContext(ScalaClassLoader.scala:88)
>> at scala.tools.nsc.util.ScalaClassLoader$class.run(ScalaClassLoader.scala:78)
>> at scala.tools.nsc.util.ScalaClassLoader$URLClassLoader.run(ScalaClassLoader.scala:101)
>> at scala.tools.nsc.ObjectRunner$.run(ObjectRunner.scala:33)
>> at scala.tools.nsc.ObjectRunner$.runAndCatch(ObjectRunner.scala:40)
>> at scala.tools.nsc.ScriptRunner.scala$tools$nsc$ScriptRunner$$runCompiled(ScriptRunner.scala:171)
>> at scala.tools.nsc.ScriptRunner$$anonfun$runScript$1.apply(ScriptRunner.scala:188)
>> at scala.tools.nsc.ScriptRunner$$anonfun$runScript$1.apply(ScriptRunner.scala:188)
>> at scala.tools.nsc.ScriptRunner$$anonfun$withCompiledScript$1.apply$mcZ$sp(ScriptRunner.scala:157)
>> at scala.tools.nsc.ScriptRunner$$anonfun$withCompiledScript$1.apply(ScriptRunner.scala:131)
>> at scala.tools.nsc.ScriptRunner$$anonfun$withCompiledScript$1.apply(ScriptRunner.scala:131)
>> at scala.tools.nsc.util.package$.waitingForThreads(package.scala:26)
>> at scala.tools.nsc.ScriptRunner.withCompiledScript(ScriptRunner.scala:130)
>> at scala.tools.nsc.ScriptRunner.runScript(ScriptRunner.scala:188)
>> at scala.tools.nsc.ScriptRunner.runScriptAndCatch(ScriptRunner.scala:201)
>> at scala.tools.nsc.MainGenericRunner.runTarget$1(MainGenericRunner.scala:58)
>> at scala.tools.nsc.MainGenericRunner.process(MainGenericRunner.scala:80)
>> at scala.tools.nsc.MainGenericRunner$.main(MainGenericRunner.scala:89)
>> at scala.tools.nsc.MainGenericRunner.main(MainGenericRunner.scala)
>>
>> If I run the following code
>>
>> Class.forName("com.kodak.intersystem.scripts.Intersystem").getMethods.foreach(println(_))
>>
>> I get
>>
>> public static final void com.kodak.intersystem.scripts.Intersystem.main(java.lang.String[])
>> public static final boolean com.kodak.intersystem.scripts.Intersystem.exit()
>> public static final com.kodak.intersystem.common.Properties com.kodak.intersystem.scripts.Intersystem.properties()
>> public static final void com.kodak.intersystem.scripts.Intersystem.getEnv(java.lang.String)
>> public static final void com.kodak.intersystem.scripts.Intersystem.SCALA_HOME()
>> public static final void com.kodak.intersystem.scripts.Intersystem.scalaBat_$eq(java.lang.String)
>> public static final java.lang.String com.kodak.intersystem.scripts.Intersystem.scalaBat()
>> public static final void com.kodak.intersystem.scripts.Intersystem.exit_$eq(boolean)
>> public static final org.slf4j.Logger com.kodak.intersystem.scripts.Intersystem.logger()
>> public static final void com.kodak.intersystem.scripts.Intersystem.POSTGRES_HOME()
>> public static final void com.kodak.intersystem.scripts.Intersystem.emitWarn(java.lang.String)
>> public static final void com.kodak.intersystem.scripts.Intersystem.emitError(java.lang.String)
>> public static final void com.kodak.intersystem.scripts.Intersystem.emitInfo(java.lang.String)
>> public static final void com.kodak.intersystem.scripts.Intersystem.emit(java.lang.String)
>> public static final java.lang.Class com.kodak.intersystem.scripts.Intersystem.string2Class(java.lang.String,java.lang.ClassLoader)
>> public static final void com.kodak.intersystem.scripts.Intersystem.pg_dumpExe_$eq(java.lang.String)
>> public static final java.lang.String com.kodak.intersystem.scripts.Intersystem.pg_dumpExe()
>> public final native void java.lang.Object.wait(long) throws java.lang.InterruptedException
>> public final void java.lang.Object.wait() throws java.lang.InterruptedException
>> public final void java.lang.Object.wait(long,int) throws java.lang.InterruptedException
>> public boolean java.lang.Object.equals(java.lang.Object)
>> public java.lang.String java.lang.Object.toString()
>> public native int java.lang.Object.hashCode()
>> public final native java.lang.Class java.lang.Object.getClass()
>> public final native void java.lang.Object.notify()
>> public final native void java.lang.Object.notifyAll()
>>
>> so I cannot figure out why the Scala reflection API is having trouble with invoking my main method.
>>
>> Cheers, Eric
> This e-mail message may contain privileged and/or confidential information, and is intended to be received only by persons entitled
> to receive such information. If you have received this e-mail in error, please notify the sender immediately. Please delete it and
> all attachments from any servers, hard drives or any other media. Other use of this e-mail by you is strictly prohibited.
>
> All e-mails and attachments sent and received are subject to monitoring, reading and archival by Monsanto, including its
> subsidiaries. The recipient of this e-mail is solely responsible for checking for the presence of "Viruses" or other "Malware".
> Monsanto, along with its subsidiaries, accepts no liability for any damage caused by any such code transmitted by or accompanying
> this e-mail or any attachment.
>
>
> The information contained in this email may be subject to the export control laws and regulations of the United States, potentially
> including but not limited to the Export Administration Regulations (EAR) and sanctions regulations issued by the U.S. Department of
> Treasury, Office of Foreign Asset Controls (OFAC). As a recipient of this information you are obligated to comply with all
> applicable U.S. export laws and regulations.
>

Walter Cazzola
Joined: 2012-01-24,
User offline. Last seen 42 years 45 weeks ago.
Re: Joy of Reflection

If Intersystem defines its own constructor the one without parameters is
not created. To get an instance in such a case you have to retrieve the
constructor with getDeclaredConstructors and call it with the right
parameters.

I HTH

Walter

On Mon, 23 Jan 2012, Eric Kolotyluk wrote:

> The class is defined as
>
> object Intersystem extends Emitter {
> ...
>
> Does that create a no-arg constructor? I just assumed it did.
>
> Cheers, Eric
>
> On 2012-01-23 4:43 PM, RICHT, RYAN JERRY (AG/1005) wrote:
>> Dear Eric,
>>
>> Does the class in question have a no-arg constructor? When you call
>> ".newInstance" I believe it tries to invoke (only) the no-arg constructor.
>> If you don't have one, you will get an InstantiationException.
>>
>> Ryan Richt
>> Monsanto
>>
>>
>> On Jan 23, 2012, at 5:22 PM, Eric Kolotyluk wrote:
>>
>>> I've been trying to get some simple reflection working but cannot seem to
>>> figure it out. The code I am using from
>>> http://stackoverflow.com/questions/1469958/scala-how-do-i-dynamically-in...
>>> looks like
>>>
>>> val mainClass =
>>> Class.forName("com.kodak.intersystem.scripts.Intersystem").newInstance.asInstanceOf[{
>>> def main(arguments : Array[String]) }]
>>> mainClass.main(arguments)
>>>
>>> but when it runs I get (see below) which does not mean very much.
>>> Basically I am just trying to invoke the main method of another class in
>>> the standard fashion.
>>>
>>> java.lang.InstantiationException:
>>> com.kodak.intersystem.scripts.Intersystem
>>> at java.lang.Class.newInstance0(Class.java:340)
>>> at java.lang.Class.newInstance(Class.java:308)
>>> at Main$.main(Compile.scala:89)
>>> at Main.main(Compile.scala)
>>> at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
>>> at
>>> sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
>>> at
>>> sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
>>> at java.lang.reflect.Method.invoke(Method.java:597)
>>> at
>>> scala.tools.nsc.util.ScalaClassLoader$$anonfun$run$1.apply(ScalaClassLoader.scala:78)
>>> at
>>> scala.tools.nsc.util.ScalaClassLoader$class.asContext(ScalaClassLoader.scala:24)
>>> at
>>> scala.tools.nsc.util.ScalaClassLoader$URLClassLoader.asContext(ScalaClassLoader.scala:88)
>>> at
>>> scala.tools.nsc.util.ScalaClassLoader$class.run(ScalaClassLoader.scala:78)
>>> at
>>> scala.tools.nsc.util.ScalaClassLoader$URLClassLoader.run(ScalaClassLoader.scala:101)
>>> at scala.tools.nsc.ObjectRunner$.run(ObjectRunner.scala:33)
>>> at
>>> scala.tools.nsc.ObjectRunner$.runAndCatch(ObjectRunner.scala:40)
>>> at
>>> scala.tools.nsc.ScriptRunner.scala$tools$nsc$ScriptRunner$$runCompiled(ScriptRunner.scala:171)
>>> at
>>> scala.tools.nsc.ScriptRunner$$anonfun$runScript$1.apply(ScriptRunner.scala:188)
>>> at
>>> scala.tools.nsc.ScriptRunner$$anonfun$runScript$1.apply(ScriptRunner.scala:188)
>>> at
>>> scala.tools.nsc.ScriptRunner$$anonfun$withCompiledScript$1.apply$mcZ$sp(ScriptRunner.scala:157)
>>> at
>>> scala.tools.nsc.ScriptRunner$$anonfun$withCompiledScript$1.apply(ScriptRunner.scala:131)
>>> at
>>> scala.tools.nsc.ScriptRunner$$anonfun$withCompiledScript$1.apply(ScriptRunner.scala:131)
>>> at
>>> scala.tools.nsc.util.package$.waitingForThreads(package.scala:26)
>>> at
>>> scala.tools.nsc.ScriptRunner.withCompiledScript(ScriptRunner.scala:130)
>>> at scala.tools.nsc.ScriptRunner.runScript(ScriptRunner.scala:188)
>>> at
>>> scala.tools.nsc.ScriptRunner.runScriptAndCatch(ScriptRunner.scala:201)
>>> at
>>> scala.tools.nsc.MainGenericRunner.runTarget$1(MainGenericRunner.scala:58)
>>> at
>>> scala.tools.nsc.MainGenericRunner.process(MainGenericRunner.scala:80)
>>> at
>>> scala.tools.nsc.MainGenericRunner$.main(MainGenericRunner.scala:89)
>>> at scala.tools.nsc.MainGenericRunner.main(MainGenericRunner.scala)
>>>
>>> If I run the following code
>>>
>>> Class.forName("com.kodak.intersystem.scripts.Intersystem").getMethods.foreach(println(_))
>>>
>>> I get
>>>
>>> public static final void
>>> com.kodak.intersystem.scripts.Intersystem.main(java.lang.String[])
>>> public static final boolean
>>> com.kodak.intersystem.scripts.Intersystem.exit()
>>> public static final com.kodak.intersystem.common.Properties
>>> com.kodak.intersystem.scripts.Intersystem.properties()
>>> public static final void
>>> com.kodak.intersystem.scripts.Intersystem.getEnv(java.lang.String)
>>> public static final void
>>> com.kodak.intersystem.scripts.Intersystem.SCALA_HOME()
>>> public static final void
>>> com.kodak.intersystem.scripts.Intersystem.scalaBat_$eq(java.lang.String)
>>> public static final java.lang.String
>>> com.kodak.intersystem.scripts.Intersystem.scalaBat()
>>> public static final void
>>> com.kodak.intersystem.scripts.Intersystem.exit_$eq(boolean)
>>> public static final org.slf4j.Logger
>>> com.kodak.intersystem.scripts.Intersystem.logger()
>>> public static final void
>>> com.kodak.intersystem.scripts.Intersystem.POSTGRES_HOME()
>>> public static final void
>>> com.kodak.intersystem.scripts.Intersystem.emitWarn(java.lang.String)
>>> public static final void
>>> com.kodak.intersystem.scripts.Intersystem.emitError(java.lang.String)
>>> public static final void
>>> com.kodak.intersystem.scripts.Intersystem.emitInfo(java.lang.String)
>>> public static final void
>>> com.kodak.intersystem.scripts.Intersystem.emit(java.lang.String)
>>> public static final java.lang.Class
>>> com.kodak.intersystem.scripts.Intersystem.string2Class(java.lang.String,java.lang.ClassLoader)
>>> public static final void
>>> com.kodak.intersystem.scripts.Intersystem.pg_dumpExe_$eq(java.lang.String)
>>> public static final java.lang.String
>>> com.kodak.intersystem.scripts.Intersystem.pg_dumpExe()
>>> public final native void java.lang.Object.wait(long) throws
>>> java.lang.InterruptedException
>>> public final void java.lang.Object.wait() throws
>>> java.lang.InterruptedException
>>> public final void java.lang.Object.wait(long,int) throws
>>> java.lang.InterruptedException
>>> public boolean java.lang.Object.equals(java.lang.Object)
>>> public java.lang.String java.lang.Object.toString()
>>> public native int java.lang.Object.hashCode()
>>> public final native java.lang.Class java.lang.Object.getClass()
>>> public final native void java.lang.Object.notify()
>>> public final native void java.lang.Object.notifyAll()
>>>
>>> so I cannot figure out why the Scala reflection API is having trouble with
>>> invoking my main method.
>>>
>>> Cheers, Eric
>> This e-mail message may contain privileged and/or confidential information,
>> and is intended to be received only by persons entitled
>> to receive such information. If you have received this e-mail in error,
>> please notify the sender immediately. Please delete it and
>> all attachments from any servers, hard drives or any other media. Other use
>> of this e-mail by you is strictly prohibited.
>>
>> All e-mails and attachments sent and received are subject to monitoring,
>> reading and archival by Monsanto, including its
>> subsidiaries. The recipient of this e-mail is solely responsible for
>> checking for the presence of "Viruses" or other "Malware".
>> Monsanto, along with its subsidiaries, accepts no liability for any damage
>> caused by any such code transmitted by or accompanying
>> this e-mail or any attachment.
>>
>>
>> The information contained in this email may be subject to the export
>> control laws and regulations of the United States, potentially
>> including but not limited to the Export Administration Regulations (EAR)
>> and sanctions regulations issued by the U.S. Department of
>> Treasury, Office of Foreign Asset Controls (OFAC). As a recipient of this
>> information you are obligated to comply with all
>> applicable U.S. export laws and regulations.
>>
>

Lars Hupel
Joined: 2010-06-23,
User offline. Last seen 44 weeks 3 days ago.
Re: Joy of Reflection

> The class is defined as
>
> object Intersystem extends Emitter {
> ....
>
> Does that create a no-arg constructor? I just assumed it did.

Do you even need a new instance? It should be sufficient to call the
static forwarder method on class "Intersystem" which should properly
initialize the object "Intersystem" and call the main method there.

kolotyluk
Joined: 2010-06-04,
User offline. Last seen 5 weeks 15 hours ago.
Re: Joy of Reflection

Intersystem does not define any constructors, and Emitter is a trait
that does not define any constructors either.

Is it the case that if you define a simple object this way then it uses
a no-arg constructor by default?

Cheers, Eric

On 2012-01-24 1:12 AM, Walter Cazzola wrote:
> If Intersystem defines its own constructor the one without parameters is
> not created. To get an instance in such a case you have to retrieve the
> constructor with getDeclaredConstructors and call it with the right
> parameters.
>
> I HTH
>
> Walter
>
> On Mon, 23 Jan 2012, Eric Kolotyluk wrote:
>
>> The class is defined as
>>
>> object Intersystem extends Emitter {
>> ...
>>
>> Does that create a no-arg constructor? I just assumed it did.
>>
>> Cheers, Eric
>>
>> On 2012-01-23 4:43 PM, RICHT, RYAN JERRY (AG/1005) wrote:
>>> Dear Eric,
>>>
>>> Does the class in question have a no-arg constructor? When you call
>>> ".newInstance" I believe it tries to invoke (only) the no-arg
>>> constructor. If you don't have one, you will get an
>>> InstantiationException.
>>>
>>> Ryan Richt
>>> Monsanto
>>>
>>>
>>> On Jan 23, 2012, at 5:22 PM, Eric Kolotyluk wrote:
>>>
>>>> I've been trying to get some simple reflection working but cannot
>>>> seem to figure it out. The code I am using from
>>>> http://stackoverflow.com/questions/1469958/scala-how-do-i-dynamically-in...
>>>> looks like
>>>>
>>>> val mainClass =
>>>> Class.forName("com.kodak.intersystem.scripts.Intersystem").newInstance.asInstanceOf[{
>>>> def main(arguments : Array[String]) }]
>>>> mainClass.main(arguments)
>>>>
>>>> but when it runs I get (see below) which does not mean very much.
>>>> Basically I am just trying to invoke the main method of another
>>>> class in the standard fashion.
>>>>
>>>> java.lang.InstantiationException:
>>>> com.kodak.intersystem.scripts.Intersystem
>>>> at java.lang.Class.newInstance0(Class.java:340)
>>>> at java.lang.Class.newInstance(Class.java:308)
>>>> at Main$.main(Compile.scala:89)
>>>> at Main.main(Compile.scala)
>>>> at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
>>>> at
>>>> sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
>>>> at
>>>> sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
>>>> at java.lang.reflect.Method.invoke(Method.java:597)
>>>> at
>>>> scala.tools.nsc.util.ScalaClassLoader$$anonfun$run$1.apply(ScalaClassLoader.scala:78)
>>>> at
>>>> scala.tools.nsc.util.ScalaClassLoader$class.asContext(ScalaClassLoader.scala:24)
>>>> at
>>>> scala.tools.nsc.util.ScalaClassLoader$URLClassLoader.asContext(ScalaClassLoader.scala:88)
>>>> at
>>>> scala.tools.nsc.util.ScalaClassLoader$class.run(ScalaClassLoader.scala:78)
>>>> at
>>>> scala.tools.nsc.util.ScalaClassLoader$URLClassLoader.run(ScalaClassLoader.scala:101)
>>>> at scala.tools.nsc.ObjectRunner$.run(ObjectRunner.scala:33)
>>>> at
>>>> scala.tools.nsc.ObjectRunner$.runAndCatch(ObjectRunner.scala:40)
>>>> at
>>>> scala.tools.nsc.ScriptRunner.scala$tools$nsc$ScriptRunner$$runCompiled(ScriptRunner.scala:171)
>>>> at
>>>> scala.tools.nsc.ScriptRunner$$anonfun$runScript$1.apply(ScriptRunner.scala:188)
>>>> at
>>>> scala.tools.nsc.ScriptRunner$$anonfun$runScript$1.apply(ScriptRunner.scala:188)
>>>> at
>>>> scala.tools.nsc.ScriptRunner$$anonfun$withCompiledScript$1.apply$mcZ$sp(ScriptRunner.scala:157)
>>>> at
>>>> scala.tools.nsc.ScriptRunner$$anonfun$withCompiledScript$1.apply(ScriptRunner.scala:131)
>>>> at
>>>> scala.tools.nsc.ScriptRunner$$anonfun$withCompiledScript$1.apply(ScriptRunner.scala:131)
>>>> at
>>>> scala.tools.nsc.util.package$.waitingForThreads(package.scala:26)
>>>> at
>>>> scala.tools.nsc.ScriptRunner.withCompiledScript(ScriptRunner.scala:130)
>>>>
>>>> at
>>>> scala.tools.nsc.ScriptRunner.runScript(ScriptRunner.scala:188)
>>>> at
>>>> scala.tools.nsc.ScriptRunner.runScriptAndCatch(ScriptRunner.scala:201)
>>>> at
>>>> scala.tools.nsc.MainGenericRunner.runTarget$1(MainGenericRunner.scala:58)
>>>> at
>>>> scala.tools.nsc.MainGenericRunner.process(MainGenericRunner.scala:80)
>>>> at
>>>> scala.tools.nsc.MainGenericRunner$.main(MainGenericRunner.scala:89)
>>>> at
>>>> scala.tools.nsc.MainGenericRunner.main(MainGenericRunner.scala)
>>>>
>>>> If I run the following code
>>>>
>>>>
>>>> Class.forName("com.kodak.intersystem.scripts.Intersystem").getMethods.foreach(println(_))
>>>>
>>>> I get
>>>>
>>>> public static final void
>>>> com.kodak.intersystem.scripts.Intersystem.main(java.lang.String[])
>>>> public static final boolean
>>>> com.kodak.intersystem.scripts.Intersystem.exit()
>>>> public static final com.kodak.intersystem.common.Properties
>>>> com.kodak.intersystem.scripts.Intersystem.properties()
>>>> public static final void
>>>> com.kodak.intersystem.scripts.Intersystem.getEnv(java.lang.String)
>>>> public static final void
>>>> com.kodak.intersystem.scripts.Intersystem.SCALA_HOME()
>>>> public static final void
>>>> com.kodak.intersystem.scripts.Intersystem.scalaBat_$eq(java.lang.String)
>>>>
>>>> public static final java.lang.String
>>>> com.kodak.intersystem.scripts.Intersystem.scalaBat()
>>>> public static final void
>>>> com.kodak.intersystem.scripts.Intersystem.exit_$eq(boolean)
>>>> public static final org.slf4j.Logger
>>>> com.kodak.intersystem.scripts.Intersystem.logger()
>>>> public static final void
>>>> com.kodak.intersystem.scripts.Intersystem.POSTGRES_HOME()
>>>> public static final void
>>>> com.kodak.intersystem.scripts.Intersystem.emitWarn(java.lang.String)
>>>> public static final void
>>>> com.kodak.intersystem.scripts.Intersystem.emitError(java.lang.String)
>>>> public static final void
>>>> com.kodak.intersystem.scripts.Intersystem.emitInfo(java.lang.String)
>>>> public static final void
>>>> com.kodak.intersystem.scripts.Intersystem.emit(java.lang.String)
>>>> public static final java.lang.Class
>>>> com.kodak.intersystem.scripts.Intersystem.string2Class(java.lang.String,java.lang.ClassLoader)
>>>> public static final void
>>>> com.kodak.intersystem.scripts.Intersystem.pg_dumpExe_$eq(java.lang.String)
>>>> public static final java.lang.String
>>>> com.kodak.intersystem.scripts.Intersystem.pg_dumpExe()
>>>> public final native void java.lang.Object.wait(long) throws
>>>> java.lang.InterruptedException
>>>> public final void java.lang.Object.wait() throws
>>>> java.lang.InterruptedException
>>>> public final void java.lang.Object.wait(long,int) throws
>>>> java.lang.InterruptedException
>>>> public boolean java.lang.Object.equals(java.lang.Object)
>>>> public java.lang.String java.lang.Object.toString()
>>>> public native int java.lang.Object.hashCode()
>>>> public final native java.lang.Class java.lang.Object.getClass()
>>>> public final native void java.lang.Object.notify()
>>>> public final native void java.lang.Object.notifyAll()
>>>>
>>>> so I cannot figure out why the Scala reflection API is having
>>>> trouble with invoking my main method.
>>>>
>>>> Cheers, Eric
>>> This e-mail message may contain privileged and/or confidential
>>> information, and is intended to be received only by persons entitled
>>> to receive such information. If you have received this e-mail in
>>> error, please notify the sender immediately. Please delete it and
>>> all attachments from any servers, hard drives or any other media.
>>> Other use of this e-mail by you is strictly prohibited.
>>>
>>> All e-mails and attachments sent and received are subject to
>>> monitoring, reading and archival by Monsanto, including its
>>> subsidiaries. The recipient of this e-mail is solely responsible for
>>> checking for the presence of "Viruses" or other "Malware".
>>> Monsanto, along with its subsidiaries, accepts no liability for any
>>> damage caused by any such code transmitted by or accompanying
>>> this e-mail or any attachment.
>>>
>>>
>>> The information contained in this email may be subject to the export
>>> control laws and regulations of the United States, potentially
>>> including but not limited to the Export Administration Regulations
>>> (EAR) and sanctions regulations issued by the U.S. Department of
>>> Treasury, Office of Foreign Asset Controls (OFAC). As a recipient
>>> of this information you are obligated to comply with all
>>> applicable U.S. export laws and regulations.
>>>
>>
>

kolotyluk
Joined: 2010-06-04,
User offline. Last seen 5 weeks 15 hours ago.
Re: Re: Joy of Reflection

On 2012-01-24 1:40 AM, Lars Hupel wrote:
>> The class is defined as
>>
>> object Intersystem extends Emitter {
>> ....
>>
>> Does that create a no-arg constructor? I just assumed it did.
> Do you even need a new instance? It should be sufficient to call the
> static forwarder method on class "Intersystem" which should properly
> initialize the object "Intersystem" and call the main method there.
>
Good point, I forgot that object is already constructed. If I change
'object' to 'class' then the code works :-))

As for the rest, I have no idea what you mean. Can you provide a code
example that should work with reflectively calling an object?

Cheers, Eric

Alex Cruise
Joined: 2008-12-17,
User offline. Last seen 2 years 26 weeks ago.
Re: Re: Joy of Reflection
On Tue, Jan 24, 2012 at 8:59 AM, Eric Kolotyluk <eric.kolotyluk@gmail.com> wrote:
Good point, I forgot that object is already constructed. If I change 'object' to 'class' then the code works :-))

But then it's not a singleton anymore...   
As for the rest, I have no idea what you mean. Can you provide a code example that should work with reflectively calling an object?

Something like this:
val fooInstance = Class.forName("com.example.Foo$").\  getField("MODULE$").\  get(null).\   asInstanceOf[Foo.type]
-0xe1a
kolotyluk
Joined: 2010-06-04,
User offline. Last seen 5 weeks 15 hours ago.
Re: Re: Joy of Reflection
OK I got it working with

      val objectInstance = Class.forName("com.kodak.intersystem.scripts.Intersystem$").getField("MODULE$").get(null).asInstanceOf[{ def main(arguments : Array[String]) }]
      objectInstance.main(arguments)

Thanks so much - I really appreciate it :-))

I had to replace

  asInstanceOf[com.kodak.intersystem.scripts.Intersystem.type]

with

  asInstanceOf[{ def main(arguments : Array[String]) }]

as com.kodak.intersystem.scripts.Intersystem does not exist at compile time, which is why I have to use reflection.

This would make for a good example somewhere in the Scala documentation or wiki of how to reflectively invoke objects.

Cheers, Eric

On 2012-01-24 9:52 AM, Alex Cruise wrote:
SEg [at] mail [dot] gmail [dot] com" type="cite"> On Tue, Jan 24, 2012 at 8:59 AM, Eric Kolotyluk <eric [dot] kolotyluk [at] gmail [dot] com" rel="nofollow">eric.kolotyluk@gmail.com> wrote:
Good point, I forgot that object is already constructed. If I change 'object' to 'class' then the code works :-))

But then it's not a singleton anymore...   
As for the rest, I have no idea what you mean. Can you provide a code example that should work with reflectively calling an object?

Something like this:
val fooInstance = Class.forName("com.example.Foo$").\   getField("MODULE$").\   get(null).\   asInstanceOf[Foo.type]
-0xe1a
Lars Hupel
Joined: 2010-06-23,
User offline. Last seen 44 weeks 3 days ago.
Re: Joy of Reflection

> As for the rest, I have no idea what you mean. Can you provide a code
> example that should work with reflectively calling an object?

When you define an object with a method, scalac generates a static
method with the same name on the corresponding companion class which
forwards the call to the object method.

object A {
def foo(n: Int): String = ""
}

scalac generates something like:

class A$ { // the class of the object
public String foo(int);
}

class A {
// forwards the call to A$.foo with the correct instance
public static String foo(int);
}

Speaking of reflection: It should be possible to obtain the *class* "A"
and *statically* calling the method on it -- that is, without any
instance. You don't have to obtain the `MODULE$` field.

To sum everything up:

Class.forName("A").getDeclaredMethod("main",
classOf[Array[String]]).invoke(null, ...)

kolotyluk
Joined: 2010-06-04,
User offline. Last seen 5 weeks 15 hours ago.
Re: Re: Joy of Reflection

Very nice explanation. Thanks muchly :-)

Cheers, Eric

On 2012-01-24 1:07 PM, Lars Hupel wrote:
>> As for the rest, I have no idea what you mean. Can you provide a code
>> example that should work with reflectively calling an object?
> When you define an object with a method, scalac generates a static
> method with the same name on the corresponding companion class which
> forwards the call to the object method.
>
> object A {
> def foo(n: Int): String = ""
> }
>
> scalac generates something like:
>
> class A$ { // the class of the object
> public String foo(int);
> }
>
> class A {
> // forwards the call to A$.foo with the correct instance
> public static String foo(int);
> }
>
> Speaking of reflection: It should be possible to obtain the *class* "A"
> and *statically* calling the method on it -- that is, without any
> instance. You don't have to obtain the `MODULE$` field.
>
> To sum everything up:
>
> Class.forName("A").getDeclaredMethod("main",
> classOf[Array[String]]).invoke(null, ...)
>

kolotyluk
Joined: 2010-06-04,
User offline. Last seen 5 weeks 15 hours ago.
Re: Re: Joy of Reflection

OK - I am not sure what changed, but the Scala compiler was generating

Intersystem$.class

but is now generating

Intersystem$$anonfun$main$1.class

instead. What is going on?

Cheers, Eric

On 2012-01-26 11:41 AM, Eric Kolotyluk wrote:
> Very nice explanation. Thanks muchly :-)
>
> Cheers, Eric
>
> On 2012-01-24 1:07 PM, Lars Hupel wrote:
>>> As for the rest, I have no idea what you mean. Can you provide a code
>>> example that should work with reflectively calling an object?
>> When you define an object with a method, scalac generates a static
>> method with the same name on the corresponding companion class which
>> forwards the call to the object method.
>>
>> object A {
>> def foo(n: Int): String = ""
>> }
>>
>> scalac generates something like:
>>
>> class A$ { // the class of the object
>> public String foo(int);
>> }
>>
>> class A {
>> // forwards the call to A$.foo with the correct instance
>> public static String foo(int);
>> }
>>
>> Speaking of reflection: It should be possible to obtain the *class* "A"
>> and *statically* calling the method on it -- that is, without any
>> instance. You don't have to obtain the `MODULE$` field.
>>
>> To sum everything up:
>>
>> Class.forName("A").getDeclaredMethod("main",
>> classOf[Array[String]]).invoke(null, ...)
>>

kolotyluk
Joined: 2010-06-04,
User offline. Last seen 5 weeks 15 hours ago.
Re: Re: Joy of Reflection

Actually, it was always generating Intersystem$$anonfun$main$1.class -
but for some reason it is not generating Intersystem$.class any more?

Cheers, Eric

On 2012-01-29 3:23 PM, Eric Kolotyluk wrote:
> OK - I am not sure what changed, but the Scala compiler was generating
>
> Intersystem$.class
>
> but is now generating
>
> Intersystem$$anonfun$main$1.class
>
> instead. What is going on?
>
> Cheers, Eric
>
> On 2012-01-26 11:41 AM, Eric Kolotyluk wrote:
>> Very nice explanation. Thanks muchly :-)
>>
>> Cheers, Eric
>>
>> On 2012-01-24 1:07 PM, Lars Hupel wrote:
>>>> As for the rest, I have no idea what you mean. Can you provide a code
>>>> example that should work with reflectively calling an object?
>>> When you define an object with a method, scalac generates a static
>>> method with the same name on the corresponding companion class which
>>> forwards the call to the object method.
>>>
>>> object A {
>>> def foo(n: Int): String = ""
>>> }
>>>
>>> scalac generates something like:
>>>
>>> class A$ { // the class of the object
>>> public String foo(int);
>>> }
>>>
>>> class A {
>>> // forwards the call to A$.foo with the correct instance
>>> public static String foo(int);
>>> }
>>>
>>> Speaking of reflection: It should be possible to obtain the *class* "A"
>>> and *statically* calling the method on it -- that is, without any
>>> instance. You don't have to obtain the `MODULE$` field.
>>>
>>> To sum everything up:
>>>
>>> Class.forName("A").getDeclaredMethod("main",
>>> classOf[Array[String]]).invoke(null, ...)
>>>

Lars Hupel
Joined: 2010-06-23,
User offline. Last seen 44 weeks 3 days ago.
Re: Joy of Reflection

> Actually, it was always generating Intersystem$$anonfun$main$1.class -
> but for some reason it is not generating Intersystem$.class any more?

The class `Intersystem$` has to be there, as it is the class of `object
Intersystem`. I don't know what went wrong, but try to give a small
working snippet of your code to see whether it can be reproduced.

kolotyluk
Joined: 2010-06-04,
User offline. Last seen 5 weeks 15 hours ago.
Re: Re: Joy of Reflection

On 2012-01-29 5:33 PM, Lars Hupel wrote:
>> Actually, it was always generating Intersystem$$anonfun$main$1.class -
>> but for some reason it is not generating Intersystem$.class any more?
> The class `Intersystem$` has to be there, as it is the class of `object
> Intersystem`. I don't know what went wrong, but try to give a small
> working snippet of your code to see whether it can be reproduced.

OK, found the problem. Somehow I picked up an older version of my source
file that used 'class Intersystem' instead of 'object Intersystem' so I
did not realize the change.

Everything works now, and I have put a check in my code for the
ClassNotFoundException to print a reminder of what the problem probably is.

Cheers, Eric

Copyright © 2012 École Polytechnique Fédérale de Lausanne (EPFL), Lausanne, Switzerland