Skip to content

Commit

Permalink
Classloader stuff
Browse files Browse the repository at this point in the history
  • Loading branch information
Philip Andrew committed Aug 17, 2016
1 parent a318d15 commit 4920e15
Show file tree
Hide file tree
Showing 3 changed files with 96 additions and 1 deletion.
2 changes: 1 addition & 1 deletion src/main/scala/osgidemo/impl/AkkaBean.scala
Expand Up @@ -47,7 +47,7 @@ class AkkaBean {
println("Start 2")
val sysConfig = getActorSystemConfiguration(bundleContext)
println("Start 3")
val actorFactory = OsgiActorSystemFactory(bundleContext, sysConfig)
val actorFactory = MyOsgiActorSystemFactory(bundleContext, sysConfig)
println("Start 4")
system = Some(actorFactory.createActorSystem(Option(getActorSystemName(bundleContext))))
println("Start 5")
Expand Down
35 changes: 35 additions & 0 deletions src/main/scala/osgidemo/impl/MyBundleDelegatingClassLoader.scala
@@ -0,0 +1,35 @@
package osgidemo.impl

import java.net.URL
import java.util.Enumeration

import akka.osgi.{BundleDelegatingClassLoader, OsgiActorSystemFactory}
import org.osgi.framework.{Bundle, BundleContext}

import scala.annotation.tailrec


object MyBundleDelegatingClassLoader {
/*
* Create a bundle delegating ClassLoader for the bundle context's bundle
*/
def apply(context: BundleContext): MyBundleDelegatingClassLoader = new MyBundleDelegatingClassLoader(context.getBundle, null)

def apply(context: BundleContext, fallBackCLassLoader: Option[ClassLoader]): MyBundleDelegatingClassLoader =
new MyBundleDelegatingClassLoader(context.getBundle, fallBackCLassLoader.orNull)
}


case class MyBundleDelegatingClassLoader(bundle: Bundle, fallBackClassLoader: ClassLoader) extends BundleDelegatingClassLoader(bundle, fallBackClassLoader) {

override def findResource(name: String): URL = {
println("####" + name)
super.findResource(name)
}

override def findResources(name: String): Enumeration[URL] = {
println("####" + name)
super.findResources(name)
}

}
60 changes: 60 additions & 0 deletions src/main/scala/osgidemo/impl/MyOsgiActorSystemFactory.scala
@@ -0,0 +1,60 @@
package osgidemo.impl

import akka.actor.ActorSystem
import akka.osgi.{ActorSystemActivator, BundleDelegatingClassLoader}
import com.typesafe.config.{Config, ConfigFactory}
import org.osgi.framework.BundleContext

/**
* Factory class to create ActorSystem implementations in an OSGi environment. This mainly involves dealing with
* bundle classloaders appropriately to ensure that configuration files and classes get loaded properly
*/
class MyOsgiActorSystemFactory(val context: BundleContext, val fallbackClassLoader: Option[ClassLoader], config: Config = ConfigFactory.empty) {

/*
* Classloader that delegates to the bundle for which the factory is creating an ActorSystem
*/
private val classloader = MyBundleDelegatingClassLoader(context, fallbackClassLoader)

/**
* Creates the [[akka.actor.ActorSystem]], using the name specified
*/
def createActorSystem(name: String): ActorSystem = createActorSystem(Option(name))

/**
* Creates the [[akka.actor.ActorSystem]], using the name specified.
*
* A default name (`bundle-<bundle id>-ActorSystem`) is assigned when you pass along [[scala.None]] instead.
*/
def createActorSystem(name: Option[String]): ActorSystem =
ActorSystem(actorSystemName(name), actorSystemConfig(context), classloader)

/**
* Strategy method to create the Config for the ActorSystem
* ensuring that the default/reference configuration is loaded from the akka-actor bundle.
* Configuration files found in akka-actor bundle
*/
def actorSystemConfig(context: BundleContext): Config = {
config.withFallback(ConfigFactory.load(classloader).withFallback(ConfigFactory.defaultReference(MyOsgiActorSystemFactory.akkaActorClassLoader)))
}

/**
* Determine the name for the [[akka.actor.ActorSystem]]
* Returns a default value of `bundle-<bundle id>-ActorSystem` is no name is being specified
*/
def actorSystemName(name: Option[String]): String =
name.getOrElse("bundle-%s-ActorSystem".format(context.getBundle.getBundleId))

}

object MyOsgiActorSystemFactory {
/**
* Class loader of akka-actor bundle.
*/
def akkaActorClassLoader = classOf[ActorSystemActivator].getClassLoader

/*
* Create an [[OsgiActorSystemFactory]] instance to set up Akka in an OSGi environment
*/
def apply(context: BundleContext, config: Config): MyOsgiActorSystemFactory = new MyOsgiActorSystemFactory(context, Some(akkaActorClassLoader), config)
}

0 comments on commit 4920e15

Please sign in to comment.