I had quite some progress, I wrote a bundle that monitors a drectory and
rereates a bundle when a file changes compiling what's in
<dir>/src/main/scala and copying what's in <dir>/src/main/resources (adding
the Service-Component header when a OSGI-INF/serviceComponents.xml is
available).
If the bundle already exist the existing bundle is updated:
val in = tinyBundle.build(withBnd())
if (bundle == null) {
bundle = bundleContext.installBundle(
BundleRoot.sourceBundleUriPrefix+dir.toString, in)
} else {
bundle.update(in)
}
However while changes to resources are available immediately after the
update, changes to classes and to the serviceComponents.xml only have effect
after refreshing the packages using PackageAdmin.
Any idea why?
Cheers,
Reto
On Fri, Jan 21, 2011 at 8:05 PM, Reto Bachmann-Gmuer <
[email protected]> wrote:
> 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