am working on a server project in Kotlin where I need to dynamically load and unload modules during runtime. To achieve this, I decided to use the OSGi framework and Apache Felix as the OSGi library.
I have created a simple project where I export a service using OSGi. However, when I try to run the program, I encounter an error. Here are the relevant code snippets:
The activator:
import bundles.service.MathOperationsService
import bundles.service.MathOperationsAddImpl
import org.osgi.framework.BundleActivator
import org.osgi.framework.BundleContext
class MathOperationsActivator: BundleActivator {
override fun start(context: BundleContext?) {
context?.registerService(MathOperationsService::class.java.name, MathOperationsAddImpl(), null)
}
override fun stop(context: BundleContext?) {
// NOTE: The service is automatically unregistered.
}
}
The service interface:
interface MathOperationsService {
fun calculate(a: Int, b: Int): Int
}
The service implementation:
class MathOperationsAddImpl: MathOperationsService {
override fun calculate(a: Int, b: Int): Int {
return a + b
}
}
The mathOperationProgram:
class MathOperationProgram {
companion object {
@JvmStatic
fun main(args: Array<String>) {
val frameworkFactory = FrameworkFactory()
val framework = frameworkFactory.newFramework(null)
framework.init()
try {
framework.start()
val bundleContext = framework.bundleContext
val mathBundle: Bundle =
bundleContext.installBundle("file:/path/to/mathBundle.jar")
mathBundle.start()
val mathOperationsService = mathBundle.bundleContext.getService(
mathBundle.bundleContext.getServiceReference(MathOperationsService::class.java)
)
if (mathOperationsService != null) {
val result = mathOperationsService.calculate(3, 4)
println("Result: $result")
} else {
println("Failed to retrieve MathOperationsService")
}
} catch (e: Exception) {
println("Error: ${e.message}")
e.printStackTrace()
} finally {
framework.stop()
framework.waitForStop(0)
}
}
}
}
And the gradle task I used to create the bundle:
tasks.register("mathBundleJar", Jar::class) {
archiveFileName.set("mathBundle.jar")
manifest {
attributes(
"Bundle-Name" to "Math Operations Bundle",
"Bundle-Description" to "Bundle for Math Operations",
"Bundle-SymbolicName" to "math-bundle",
"Bundle-Vendor" to "Apache Felix",
"Bundle-Version" to "1.0.0",
"Bundle-Activator" to "bundles.MathOperationsActivator",
"Export-Package" to "bundles.service",
"Import-Package" to "org.osgi.framework, bundles.service",
)
}
duplicatesStrategy = DuplicatesStrategy.EXCLUDE
from(sourceSets.main.get().output)
dependsOn(configurations.runtimeClasspath)
from({
configurations.runtimeClasspath.get().filter { it.name.endsWith("jar") }.map { zipTree(it) }
})
}
When trying to run the MathOperationProgram I'm getting the following error:
Error: bundles.service.MathOperationsAddImpl cannot be cast to bundles.service.MathOperationsService
java.lang.ClassCastException: bundles.service.MathOperationsAddImpl cannot be cast to bundles.service.MathOperationsService
at MathOperationProgram$Companion.main(MathOperationProgram.kt:23)
at MathOperationProgram.main(MathOperationProgram.kt)
I would appreciate any guidance on resolving this error and successfully utilizing Apache Felix and OSGi for dynamic module loading in my Kotlin project. In addition, if anyone is familiar with some sample code or a tutorial available that demonstrates a similar setup with Kotlin/java and OSGi integration I would apriciate it.
Thanks