Ok I got it running with a work-around
instead of doing
nb.add(clazz)
I do
import scala.tools.nsc.interpreter.AbstractFileClassLoader
val cl = clazz.getClassLoader.asInstanceOf[AbstractFileClassLoader]
bal bytes = cl.getBytesForClass(clazz.getName)
tinyFoo.add("foo/Hello.class", new ByteArrayInputStream(bytes))
The appraoch might not work with inner classes as these are not in the List
returned by the CompilerService.
Reto
On Fri, Jan 21, 2011 at 5:10 PM, Toni Menzel <[email protected]> wrote:
> But does tinybundles (look at the (also tiny) source base) report any
> errors about that ? Let me know if we can access this virtual (in memory
> only?) class container in order to get the bytes.
>
>
> On Fri, Jan 21, 2011 at 4:47 PM, Reto Bachmann-Gmuer <
> [email protected]> wrote:
>
>> Hi Toni!
>>
>> Indeed its not possible to find the classes on disk but also getting
>> "foo/Hello.class" with the Classloader doesn't return any content
>>
>> zz>val clazz = classes(0)
>> clazz: java.lang.Class[_] = class foo.Hello
>> zz>clazz.getClassLoader.getResourceAsStream("foo/Hello.class")
>> res34: java.io.InputStream = java.util.zip.ZipFile$1@46b48bc5
>> zz>import scala.io.Source
>> import scala.io.Source
>> zz>Source.fromInputStream(res34).length
>> res36: Int = 0
>>
>> I'll have to get those bytes from the "virtual directory" used by the
>> compiler.
>>
>> Cheers,
>> Reto
>>
>>
>> On Fri, Jan 21, 2011 at 3:31 PM, Toni Menzel <[email protected]>wrote:
>>
>>> Hi Reto!
>>>
>>> Mmhh.. interesting. Though did not follow your step myself did you look
>>> into the bundle that has been generated ?
>>> I mean, you can dump it (its an inputstream) to a file and have a look ?
>>> Guess its the only way to see whats really happening. Also look if a
>>> bundle looks clean (technically) when not adding anything. Or at least
>>> nothing you declared just at runtime.
>>> Speaking of that i might see the problem. Tinybundles takes a Class type
>>> in "addClass" but just for API brevity. It really resolves the fully
>>> qualified name and tried to find it on disk.
>>> The funny full qualified class name
>>> (ine6$object$$iw$$iw$$iw$$iw$$iw$$iw$$iw$$iw$HelloWorld.class) speaks for
>>> itself - but its not about aesthetics probably ;)
>>>
>>> Can you load the (generated) bundle in your IDE (and use the
>>> aforementioned class) ?
>>>
>>> Toni
>>>
>>> On Fri, Jan 21, 2011 at 3:14 PM, Reto Bachmann-Gmuer <
>>> [email protected]> wrote:
>>>
>>>> Goal: create and install a bundle at runtime from the clerzza-console
>>>>
>>>> Starting point: Clerezza tdb launcher with additional TinyBundle and its
>>>> dependencies installed
>>>>
>>>> Welcome to the Apache Clerezza Console
>>>> Console is based on Scala version 2.8.1.final (OpenJDK 64-Bit Server VM,
>>>> Java 1.6.0_20).
>>>> Type in expressions to have them evaluated.
>>>> Hint: To execute a Felix-Shell command prepend ":f "
>>>> Type :help for more information.
>>>> zz>import org.ops4j.pax.swissbox.tinybundles.core.TinyBundles._
>>>> import org.ops4j.pax.swissbox.tinybundles.core.TinyBundles._
>>>> zz>val nb = newBundle()
>>>> nb: org.ops4j.pax.swissbox.tinybundles.core.TinyBundle =
>>>> org.ops4j.pax.swissbox.tinybundles.core.intern.TinyBundleImpl@61e14b67
>>>> zz>class HelloWorld { def hello = println("hello") }
>>>> defined class HelloWorld
>>>> zz>nb.add(classOf[HelloWorld])
>>>> res0: org.ops4j.pax.swissbox.tinybundles.core.TinyBundle =
>>>> org.ops4j.pax.swissbox.tinybundles.core.intern.TinyBundleImpl@61e14b67
>>>> zz>nb.set("Some-Key", "some value")
>>>> res1: org.ops4j.pax.swissbox.tinybundles.core.TinyBundle =
>>>> org.ops4j.pax.swissbox.tinybundles.core.intern.TinyBundleImpl@61e14b67
>>>> zz>import java.io._
>>>> import java.io._
>>>> zz>nb.add("test-file", new ByteArrayInputStream("some
>>>> test-data".getBytes("utf-8")))
>>>> res2: org.ops4j.pax.swissbox.tinybundles.core.TinyBundle =
>>>> org.ops4j.pax.swissbox.tinybundles.core.intern.TinyBundleImpl@61e14b67
>>>> zz>val in = nb.build(withBnd())
>>>> in: java.io.InputStream = java.io.PipedInputStream@5906edd5
>>>> zz>val myBundle = bundleContext.installBundle("myBundle", in)
>>>> myBundle: org.osgi.framework.Bundle =
>>>> BuildByTinyBundlestinybundles7983922728161488712UID [139]
>>>> zz>val entries = myBundle.findEntries("/", null, true)
>>>> entries: java.util.Enumeration[_] =
>>>> org.apache.felix.framework.EntryFilterEnumeration@3aa0d67c
>>>> zz>while (entries.hasMoreElements) { out println("Entry:
>>>> "+entries.nextElement) }
>>>> Entry: bundle://139.0:0/META-INF/
>>>> Entry: bundle://139.0:0/META-INF/MANIFEST.MF
>>>> Entry:
>>>> bundle://139.0:0/line6$object$$iw$$iw$$iw$$iw$$iw$$iw$$iw$$iw$HelloWorld.class
>>>> zz>headers(myBundle)
>>>> Bnd-LastModified = 1295608733169
>>>> Built-By = reto
>>>> Bundle-ManifestVersion = 2
>>>> Bundle-Name = BuildByTinyBundlestinybundles7983922728161488712UID
>>>> Bundle-SymbolicName =
>>>> BuildByTinyBundlestinybundles7983922728161488712UID
>>>> Bundle-Version = 0
>>>> Created-By = 1.6.0_20 (Sun Microsystems Inc.)
>>>> Generated-By-Ops4j-Pax-From =
>>>> BuildByTinyBundlestinybundles7983922728161488712UID
>>>> Manifest-Version = 1.0
>>>> Originally-Created-By = pax-swissbox-tinybundles-1.3.0
>>>> Private-Package = .
>>>> Some-Key = some value
>>>> SwissboxTinybundlesVersion = pax-swissbox-tinybundles-1.3.0
>>>> Tool = Bnd-0.0.313
>>>> zz>myBundle.loadClass("line6$object$$iw$$iw$$iw$$iw$$iw$$iw$$iw$$iw$HelloWorld")
>>>>
>>>> java.lang.ClassFormatError: Truncated class file
>>>> at java.lang.ClassLoader.defineClass1(Native Method)
>>>> at java.lang.ClassLoader.defineClass(ClassLoader.java:634)
>>>> at
>>>> org.apache.felix.framework.ModuleImpl$ModuleClassLoader.findClass(ModuleImpl.java:1874)
>>>> at
>>>> org.apache.felix.framework.ModuleImpl.findClassOrResourceByDelegation(ModuleImpl.java:720)
>>>> at
>>>> org.apache.felix.framework.ModuleImpl.access$300(ModuleImpl.java:73)
>>>> at
>>>> org.apache.felix.framework.ModuleImpl$ModuleClassLoader.loadClass(ModuleImpl.java:1735)
>>>> at java.lang.ClassLoader.loadClass(ClassLoader.java:266)
>>>> at
>>>> org.apache.felix.framework.ModuleImpl.getClassByDelegation(ModuleImpl.java:638)
>>>> at org.apache.felix.framework.Felix.loadBundleClass(Felix.java:1599)
>>>> at
>>>> org.apache.felix.framework.BundleImpl.loadClass(BundleImpl.java:90...zz>
>>>> zz>
>>>>
>>>>
>>>> Well not the surprising that this class created in the shell creates
>>>> problems. A bit surpring that the resource "test-file" isn't in the list.
>>>>
>>>> Let's try compiling a class using the compiler service
>>>> zz>import org.apache.clerezza.scala.scripting.CompilerService
>>>> import org.apache.clerezza.scala.scripting.CompilerService
>>>> zz>val cs = $[CompilerService]
>>>> cs: org.apache.clerezza.scala.scripting.CompilerService =
>>>> org.apache.clerezza.scala.scripting.CompilerService@54075697
>>>> zz>val source = """ package foo
>>>> | class Hello() {
>>>> | def say() { println("hello")}
>>>> | }
>>>> | """
>>>> zz>val chars = source.toCharArray
>>>> chars: Array[Char] =
>>>> Array( , p, a, c, k, a, g, e, , f, o, o,
>>>> , c, l, a, s, s, , H, e, l, l, o, (, ), , {,
>>>> , d, e, f, , s, a, y, (, ), , {, , p, r, i, n, t, l, n, (, ", h, e,
>>>> l, l, o, ", ), , },
>>>> , },
>>>> )
>>>> zz>val classes = cs.compile(List(chars))
>>>> classes: List[Class[_]] = List(class foo.Hello)
>>>> zz>val tinyFoo = newBundle()
>>>> tinyFoo: org.ops4j.pax.swissbox.tinybundles.core.TinyBundle =
>>>> org.ops4j.pax.swissbox.tinybundles.core.intern.TinyBundleImpl@6ca68dbd
>>>> zz>val fooStream = tinyFoo.build(withBnd())
>>>> fooStream: java.io.InputStream = java.io.PipedInputStream@fd855ae
>>>> zz>val fooBundle = bundleContext.installBundle("fooBundle",
>>>> fooStream)
>>>> fooBundle: org.osgi.framework.Bundle =
>>>> BuildByTinyBundlestinybundles3268593457443402016UID [145]
>>>> zz>headers(fooBundle)
>>>> Bnd-LastModified = 1295618427023
>>>> Built-By = reto
>>>> Bundle-ManifestVersion = 2
>>>> Bundle-Name = BuildByTinyBundlestinybundles3268593457443402016UID
>>>> Bundle-SymbolicName =
>>>> BuildByTinyBundlestinybundles3268593457443402016UID
>>>> Bundle-Version = 0
>>>> Created-By = 1.6.0_20 (Sun Microsystems Inc.)
>>>> Export-Package = foo
>>>> Generated-By-Ops4j-Pax-From =
>>>> BuildByTinyBundlestinybundles3268593457443402016UID
>>>> Import-Package = foo;resolution:=optional
>>>> Manifest-Version = 1.0
>>>> Originally-Created-By = pax-swissbox-tinybundles-1.3.0
>>>> SwissboxTinybundlesVersion = pax-swissbox-tinybundles-1.3.0
>>>> Tool = Bnd-0.0.313
>>>>
>>>> looking good so far, no reconnecting to the shell (ssh -p 8022
>>>> admin@localhost) to have the new bundle in the classpath
>>>>
>>>> reto@trisa-laptop:~$ ssh -p 8022 admin@localhost
>>>> admin@localhost's password:
>>>> Welcome to the Apache Clerezza Console
>>>> Console is based on Scala version 2.8.1.final (OpenJDK 64-Bit Server VM,
>>>> Java 1.6.0_20).
>>>> Type in expressions to have them evaluated.
>>>> Hint: To execute a Felix-Shell command prepend ":f "
>>>> Type :help for more information.
>>>> zz>import foo.Hello
>>>> import foo.Hello
>>>> zz>val h = new Hello()
>>>> error: error while loading Hello, class file 'foo/Hello.class' is broken
>>>> (0)
>>>> <console>:13: error: foo.Hello does not have a constructor
>>>> val h = new Hello()
>>>> ^
>>>> zz>
>>>>
>>>>
>>>> Well if you read till here, you might have a suggestion on what to try
>>>> next...
>>>>
>>>> Cheers,
>>>> Reto
>>>>
>>>>
>>>>
>>>> _______________________________________________
>>>> general mailing list
>>>> [email protected]
>>>> http://lists.ops4j.org/mailman/listinfo/general
>>>>
>>>>
>>>
>>>
>>> --
>>> *Toni Menzel - http://www.okidokiteam.com*
>>>
>>
>>
>
>
> --
> *Toni Menzel - http://www.okidokiteam.com*
>
_______________________________________________
general mailing list
[email protected]
http://lists.ops4j.org/mailman/listinfo/general