Skip to content
Browse files

dynamically load classes in Kara Exec,

add run configuration for server
  • Loading branch information...
1 parent 14eea46 commit a2241868a5d0907985b7041c60d8c72c8e42b523 @jonnyzzz jonnyzzz committed
Showing with 116 additions and 1 deletion.
  1. +23 −0 .idea/runConfigurations/Samples_Server.xml
  2. +92 −0 src/KaraExec/src/CLMain.kt
  3. +1 −1 src/KaraExec/src/Main.kt
View
23 .idea/runConfigurations/Samples_Server.xml
@@ -0,0 +1,23 @@
+<component name="ProjectRunConfigurationManager">
+ <configuration default="false" name="Samples Server" type="JetRunConfigurationType" factoryName="Kotlin" singleton="true">
+ <extension name="coverage" enabled="false" merge="false" sample_coverage="true" runner="idea" />
+ <option name="MAIN_CLASS_NAME" value="kara.setup.SetupPackage" />
+ <option name="VM_PARAMETERS" value="-Dkara.development.dist=$PROJECT_DIR$/out/artifacts/kara_dist" />
+ <option name="PROGRAM_PARAMETERS" value="s" />
+ <option name="WORKING_DIRECTORY" value="file://$PROJECT_DIR$/out/artifacts/kara_dist/samples" />
+ <option name="ALTERNATIVE_JRE_PATH_ENABLED" value="false" />
+ <option name="ALTERNATIVE_JRE_PATH" />
+ <option name="PASS_PARENT_ENVS" value="true" />
+ <module name="KaraExec" />
+ <envs>
+ <env name="KARA_HOME" value="E:\work\kara\out\artifacts\kara_dist\samples" />
+ </envs>
+ <RunnerSettings RunnerId="Run" />
+ <ConfigurationWrapper RunnerId="Run" />
+ <method>
+ <option name="BuildArtifacts" enabled="true">
+ <artifact name="kara-dist" />
+ </option>
+ </method>
+ </configuration>
+</component>
View
92 src/KaraExec/src/CLMain.kt
@@ -0,0 +1,92 @@
+package kara.setup
+
+import java.io.File
+import java.io.FileFilter
+import java.net.URL
+import java.net.URLClassLoader
+import java.net.URLDecoder
+
+fun main(args: Array<String>) {
+ val cl = URLClassLoader(HomePathResolver.collectJars(), null)
+ Thread.currentThread().setContextClassLoader(cl)
+ val clazz = cl.loadClass("kara.KaraPackage")!!
+ clazz.getMethod("main2", javaClass<Array<String>>()).invoke(null, args)
+}
+
+object HomePathResolver {
+ fun resolveHome(): File {
+ val IDEA_DEBUG = System.getProperty("kara.development.dist")
+ if (IDEA_DEBUG != null && File(IDEA_DEBUG).isDirectory()) {
+ return File(IDEA_DEBUG)
+ }
+ return File(ClassPathHelper.getClasspathEntry())
+ }
+
+ fun collectJars(): Array<URL> {
+ val home = resolveHome()
+ println("Kara home: ${home}")
+ val libs = File(home, "lib").listJars()
+ val modules = File(home, "modules").listDirs().flatMap { it.listJars().toList() }
+ return (libs + modules).map { it.toURI().toURL() }.toArray(array<URL>())
+ }
+
+ val jarFilter = object : FileFilter {
+ public override fun accept(pathname: File): Boolean
+ = pathname.isFile() && pathname.getName().endsWith(".jar") && !pathname.getName().endsWith("-sources.jar")
+ }
+
+ val dirFilter = object : FileFilter {
+ public override fun accept(pathname: File): Boolean = pathname.isDirectory()
+ }
+
+ fun File.listJars(): Array<out File> = this.listFiles(jarFilter)?:array<File>()
+ fun File.listDirs(): Array<out File> = this.listFiles(dirFilter)?:array<File>()
+
+ object ClassPathHelper {
+ fun classNameToResourcePath(className: String) = "/" + className.replace('.', '/') + ".class";
+ fun encodePlusCharacter(orig: String) = orig.replace("+", "%2B");
+
+ fun resourceUrlToClasspathEntry(className: String, resUrl: URL): String {
+ val path = classNameToResourcePath(className);
+ // we have to encode '+' character manually because otherwise URLDecoder.decode will
+ // transform it into the space character
+ var urlStr = URLDecoder.decode(encodePlusCharacter(resUrl.toExternalForm()), "UTF-8");
+ if (resUrl.getProtocol() != null) {
+ // drop path within jar file only if protocol in the URL is 'jar:'
+ if ("jar".equals(resUrl.getProtocol())) {
+ val jarSeparatorIndex = urlStr.indexOf("!");
+ if (jarSeparatorIndex >= 0) {
+ urlStr = urlStr.substring(0, jarSeparatorIndex);
+ }
+ }
+
+ var startIndex = urlStr.indexOf(':');
+ while (startIndex >= 0 && urlStr.charAt(startIndex + 1) != '/') {
+ startIndex = urlStr.indexOf(':', startIndex + 1);
+ }
+ if (startIndex >= 0) {
+ urlStr = urlStr.substring(startIndex + 1);
+ }
+ }
+
+ if (urlStr.endsWith(path)) {
+ urlStr = urlStr.substring(0, urlStr.length() - path.length());
+ }
+
+ // !Workaround for /D:/some/path/a.jar, which doesn't work if D is subst disk
+ if (urlStr.startsWith("/") && urlStr.indexOf(":") == 2) {
+ urlStr = urlStr.substring(1);
+ }
+
+ // URL may contain spaces, that is why we need to decode it
+ return File(urlStr).getPath();
+ }
+
+ private fun getClasspathEntry<T>(aClass: Class<T>): String {
+ val path = classNameToResourcePath(aClass.getName());
+ return resourceUrlToClasspathEntry(aClass.getName(), aClass.getResource(path));
+ }
+
+ public fun getClasspathEntry(): String = getClasspathEntry(javaClass);
+ }
+}
View
2 src/KaraExec/src/Main.kt
@@ -70,7 +70,7 @@ Generators:
println(s)
}
-fun main(args: Array<String>) {
+fun main2(args: Array<String>) {
BasicConfigurator.configure()
val logger = Logger.getLogger("Kara.Main")!!

0 comments on commit a224186

Please sign in to comment.
Something went wrong with that request. Please try again.