Compiling and throwing simple dynamic excepitons at runtime for JVM Planned maintenance scheduled April 23, 2019 at 23:30 UTC (7:30pm US/Eastern) Announcing the arrival of Valued Associate #679: Cesar Manara Unicorn Meta Zoo #1: Why another podcast?Named string interpolationCompiling and throwing simple dynamic excepitons at runtimeSimple factory pattern in scala (attempting to restrict use of new)Instrumentation tool using the ASM tree APISimple interface and class for holding text to be analyzedUndo format when format disappearsImplementation of stacksimple two players dice throwing gameRuntime compiler for getting/setting runtime property valuesGeneric Builder in Java needs annotation supportDeserializing a customly formatted stringCompiling and throwing simple dynamic excepitons at runtime

Understanding piped commands in GNU/Linux

Fit odd number of triplets in a measure?

Can gravitational waves pass through a black hole?

Shimano 105 brifters (5800) and Avid BB5 compatibility

How do I find my Spellcasting Ability for my D&D character?

A German immigrant ancestor has a "Registration Affidavit of Alien Enemy" on file. What does that mean exactly?

Proving that any solution to the differential equation of an oscillator can be written as a sum of sinusoids.

How to achieve cat-like agility?

How to name indistinguishable henchmen in a screenplay?

Can stored/leased 737s be used to substitute for grounded MAXs?

Why do C and C++ allow the expression (int) + 4*5?

Improvising over quartal voicings

My mentor says to set image to Fine instead of RAW — how is this different from JPG?

Why can't fire hurt Daenerys but it did to Jon Snow in season 1?

Pointing to problems without suggesting solutions

Restricting the Object Type for the get method in java HashMap

Can I take recommendation from someone I met at a conference?

How does Billy Russo acquire his 'Jigsaw' mask?

Are there any irrational/transcendental numbers for which the distribution of decimal digits is not uniform?

How do I say "this must not happen"?

malloc in main() or malloc in another function: allocating memory for a struct and its members

Can two people see the same photon?

Why does BitLocker not use RSA?

Short story about astronauts fertilizing soil with their own bodies



Compiling and throwing simple dynamic excepitons at runtime for JVM



Planned maintenance scheduled April 23, 2019 at 23:30 UTC (7:30pm US/Eastern)
Announcing the arrival of Valued Associate #679: Cesar Manara
Unicorn Meta Zoo #1: Why another podcast?Named string interpolationCompiling and throwing simple dynamic excepitons at runtimeSimple factory pattern in scala (attempting to restrict use of new)Instrumentation tool using the ASM tree APISimple interface and class for holding text to be analyzedUndo format when format disappearsImplementation of stacksimple two players dice throwing gameRuntime compiler for getting/setting runtime property valuesGeneric Builder in Java needs annotation supportDeserializing a customly formatted stringCompiling and throwing simple dynamic excepitons at runtime



.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty,.everyoneloves__bot-mid-leaderboard:empty margin-bottom:0;








0












$begingroup$


I've been using my Dynamic Exception with C# for quite some time already and it saved me a lot of time. This means, I don't have to create a new exception class for each and every case. I wanted to have the same functionality on Android and in kotlin/java so I can do this:



fun main() 
throw dynamicException("My", "Hallo exception!") // throws MyException




The DynamicException.kt file contains most of the code where the dynamicException function first initializes the source-code for the new exception by formatting a String then it uses the JavaCompiler to build the class and call the appropriate construtor. Either with or without the inner exception.



import java.io.File
import java.lang.reflect.Constructor
import java.net.URI
import java.net.URL
import java.net.URLClassLoader
import java.util.*
import javax.tools.DiagnosticCollector
import javax.tools.JavaFileObject
import javax.tools.SimpleJavaFileObject
import javax.tools.ToolProvider

fun dynamicException(name: String, message: String, inner: Throwable? = null): java.lang.Exception
val javaCompiler = ToolProvider.getSystemJavaCompiler()
val diagnosticCollector = DiagnosticCollector<JavaFileObject>()

val values = TreeMap<String, String>(String.CASE_INSENSITIVE_ORDER)
values["name"] = name
var sourceCode = SourceCodeJavaFileObject(
"com.he-dev.$nameException",
dynamicExceptionSourceCode.smartFormat(values)
)
javaCompiler.getTask(
null,
null,
diagnosticCollector,
null,
null,
arrayListOf(sourceCode)
).call()

val classLoader = URLClassLoader.newInstance(arrayOf<URL>(File("").toURI().toURL()))

var getCtor: () -> Constructor<out Any> =
val cls = Class.forName("$nameException", true, classLoader)
val ctor = if (inner == null)
cls.getConstructor(String::class.java)
else
cls.getConstructor(String::class.java, Throwable::class.java)

ctor.makeAccessible()


return if (inner == null)
getCtor().newInstance(message) as java.lang.Exception
else
getCtor().newInstance(message, inner) as java.lang.Exception



fun Constructor<out Any>.makeAccessible(): Constructor<out Any>
this.isAccessible = true
return this



val dynamicExceptionSourceCode: String = """
public class NameException extends java.lang.Exception
public NameException(java.lang.String message)
super(message);

public NameException(java.lang.String message, java.lang.Throwable inner)
super(message, inner);


""".trimIndent()

class SourceCodeJavaFileObject : SimpleJavaFileObject
private val sourceCode: CharSequence

constructor(className: String, sourceCode: CharSequence) :
super(
URI.create("string:///" + className.replace('.', '/') + JavaFileObject.Kind.SOURCE.extension),
JavaFileObject.Kind.SOURCE
)
this.sourceCode = sourceCode


override fun getCharContent(ignoreEncodingErrors: Boolean): CharSequence
return sourceCode




The string formatting is done with a string extension that can replace patterns. I based it on my C# formatter. However, it's simpler because it doesn't not support value formatting.



import java.util.*

fun String.smartFormat(values: TreeMap<String, String>): String
val regex = Regex("""(?<name>[a-z][a-z0-9_.-]*)""", RegexOption.IGNORE_CASE)
return regex.replace(this)
var key = it.groups["name"]?.value
if (values.containsKey(key)) values[key]!! else it.value





Is there anything that can be simplified or made even cleaner?










share|improve this question









$endgroup$


















    0












    $begingroup$


    I've been using my Dynamic Exception with C# for quite some time already and it saved me a lot of time. This means, I don't have to create a new exception class for each and every case. I wanted to have the same functionality on Android and in kotlin/java so I can do this:



    fun main() 
    throw dynamicException("My", "Hallo exception!") // throws MyException




    The DynamicException.kt file contains most of the code where the dynamicException function first initializes the source-code for the new exception by formatting a String then it uses the JavaCompiler to build the class and call the appropriate construtor. Either with or without the inner exception.



    import java.io.File
    import java.lang.reflect.Constructor
    import java.net.URI
    import java.net.URL
    import java.net.URLClassLoader
    import java.util.*
    import javax.tools.DiagnosticCollector
    import javax.tools.JavaFileObject
    import javax.tools.SimpleJavaFileObject
    import javax.tools.ToolProvider

    fun dynamicException(name: String, message: String, inner: Throwable? = null): java.lang.Exception
    val javaCompiler = ToolProvider.getSystemJavaCompiler()
    val diagnosticCollector = DiagnosticCollector<JavaFileObject>()

    val values = TreeMap<String, String>(String.CASE_INSENSITIVE_ORDER)
    values["name"] = name
    var sourceCode = SourceCodeJavaFileObject(
    "com.he-dev.$nameException",
    dynamicExceptionSourceCode.smartFormat(values)
    )
    javaCompiler.getTask(
    null,
    null,
    diagnosticCollector,
    null,
    null,
    arrayListOf(sourceCode)
    ).call()

    val classLoader = URLClassLoader.newInstance(arrayOf<URL>(File("").toURI().toURL()))

    var getCtor: () -> Constructor<out Any> =
    val cls = Class.forName("$nameException", true, classLoader)
    val ctor = if (inner == null)
    cls.getConstructor(String::class.java)
    else
    cls.getConstructor(String::class.java, Throwable::class.java)

    ctor.makeAccessible()


    return if (inner == null)
    getCtor().newInstance(message) as java.lang.Exception
    else
    getCtor().newInstance(message, inner) as java.lang.Exception



    fun Constructor<out Any>.makeAccessible(): Constructor<out Any>
    this.isAccessible = true
    return this



    val dynamicExceptionSourceCode: String = """
    public class NameException extends java.lang.Exception
    public NameException(java.lang.String message)
    super(message);

    public NameException(java.lang.String message, java.lang.Throwable inner)
    super(message, inner);


    """.trimIndent()

    class SourceCodeJavaFileObject : SimpleJavaFileObject
    private val sourceCode: CharSequence

    constructor(className: String, sourceCode: CharSequence) :
    super(
    URI.create("string:///" + className.replace('.', '/') + JavaFileObject.Kind.SOURCE.extension),
    JavaFileObject.Kind.SOURCE
    )
    this.sourceCode = sourceCode


    override fun getCharContent(ignoreEncodingErrors: Boolean): CharSequence
    return sourceCode




    The string formatting is done with a string extension that can replace patterns. I based it on my C# formatter. However, it's simpler because it doesn't not support value formatting.



    import java.util.*

    fun String.smartFormat(values: TreeMap<String, String>): String
    val regex = Regex("""(?<name>[a-z][a-z0-9_.-]*)""", RegexOption.IGNORE_CASE)
    return regex.replace(this)
    var key = it.groups["name"]?.value
    if (values.containsKey(key)) values[key]!! else it.value





    Is there anything that can be simplified or made even cleaner?










    share|improve this question









    $endgroup$














      0












      0








      0





      $begingroup$


      I've been using my Dynamic Exception with C# for quite some time already and it saved me a lot of time. This means, I don't have to create a new exception class for each and every case. I wanted to have the same functionality on Android and in kotlin/java so I can do this:



      fun main() 
      throw dynamicException("My", "Hallo exception!") // throws MyException




      The DynamicException.kt file contains most of the code where the dynamicException function first initializes the source-code for the new exception by formatting a String then it uses the JavaCompiler to build the class and call the appropriate construtor. Either with or without the inner exception.



      import java.io.File
      import java.lang.reflect.Constructor
      import java.net.URI
      import java.net.URL
      import java.net.URLClassLoader
      import java.util.*
      import javax.tools.DiagnosticCollector
      import javax.tools.JavaFileObject
      import javax.tools.SimpleJavaFileObject
      import javax.tools.ToolProvider

      fun dynamicException(name: String, message: String, inner: Throwable? = null): java.lang.Exception
      val javaCompiler = ToolProvider.getSystemJavaCompiler()
      val diagnosticCollector = DiagnosticCollector<JavaFileObject>()

      val values = TreeMap<String, String>(String.CASE_INSENSITIVE_ORDER)
      values["name"] = name
      var sourceCode = SourceCodeJavaFileObject(
      "com.he-dev.$nameException",
      dynamicExceptionSourceCode.smartFormat(values)
      )
      javaCompiler.getTask(
      null,
      null,
      diagnosticCollector,
      null,
      null,
      arrayListOf(sourceCode)
      ).call()

      val classLoader = URLClassLoader.newInstance(arrayOf<URL>(File("").toURI().toURL()))

      var getCtor: () -> Constructor<out Any> =
      val cls = Class.forName("$nameException", true, classLoader)
      val ctor = if (inner == null)
      cls.getConstructor(String::class.java)
      else
      cls.getConstructor(String::class.java, Throwable::class.java)

      ctor.makeAccessible()


      return if (inner == null)
      getCtor().newInstance(message) as java.lang.Exception
      else
      getCtor().newInstance(message, inner) as java.lang.Exception



      fun Constructor<out Any>.makeAccessible(): Constructor<out Any>
      this.isAccessible = true
      return this



      val dynamicExceptionSourceCode: String = """
      public class NameException extends java.lang.Exception
      public NameException(java.lang.String message)
      super(message);

      public NameException(java.lang.String message, java.lang.Throwable inner)
      super(message, inner);


      """.trimIndent()

      class SourceCodeJavaFileObject : SimpleJavaFileObject
      private val sourceCode: CharSequence

      constructor(className: String, sourceCode: CharSequence) :
      super(
      URI.create("string:///" + className.replace('.', '/') + JavaFileObject.Kind.SOURCE.extension),
      JavaFileObject.Kind.SOURCE
      )
      this.sourceCode = sourceCode


      override fun getCharContent(ignoreEncodingErrors: Boolean): CharSequence
      return sourceCode




      The string formatting is done with a string extension that can replace patterns. I based it on my C# formatter. However, it's simpler because it doesn't not support value formatting.



      import java.util.*

      fun String.smartFormat(values: TreeMap<String, String>): String
      val regex = Regex("""(?<name>[a-z][a-z0-9_.-]*)""", RegexOption.IGNORE_CASE)
      return regex.replace(this)
      var key = it.groups["name"]?.value
      if (values.containsKey(key)) values[key]!! else it.value





      Is there anything that can be simplified or made even cleaner?










      share|improve this question









      $endgroup$




      I've been using my Dynamic Exception with C# for quite some time already and it saved me a lot of time. This means, I don't have to create a new exception class for each and every case. I wanted to have the same functionality on Android and in kotlin/java so I can do this:



      fun main() 
      throw dynamicException("My", "Hallo exception!") // throws MyException




      The DynamicException.kt file contains most of the code where the dynamicException function first initializes the source-code for the new exception by formatting a String then it uses the JavaCompiler to build the class and call the appropriate construtor. Either with or without the inner exception.



      import java.io.File
      import java.lang.reflect.Constructor
      import java.net.URI
      import java.net.URL
      import java.net.URLClassLoader
      import java.util.*
      import javax.tools.DiagnosticCollector
      import javax.tools.JavaFileObject
      import javax.tools.SimpleJavaFileObject
      import javax.tools.ToolProvider

      fun dynamicException(name: String, message: String, inner: Throwable? = null): java.lang.Exception
      val javaCompiler = ToolProvider.getSystemJavaCompiler()
      val diagnosticCollector = DiagnosticCollector<JavaFileObject>()

      val values = TreeMap<String, String>(String.CASE_INSENSITIVE_ORDER)
      values["name"] = name
      var sourceCode = SourceCodeJavaFileObject(
      "com.he-dev.$nameException",
      dynamicExceptionSourceCode.smartFormat(values)
      )
      javaCompiler.getTask(
      null,
      null,
      diagnosticCollector,
      null,
      null,
      arrayListOf(sourceCode)
      ).call()

      val classLoader = URLClassLoader.newInstance(arrayOf<URL>(File("").toURI().toURL()))

      var getCtor: () -> Constructor<out Any> =
      val cls = Class.forName("$nameException", true, classLoader)
      val ctor = if (inner == null)
      cls.getConstructor(String::class.java)
      else
      cls.getConstructor(String::class.java, Throwable::class.java)

      ctor.makeAccessible()


      return if (inner == null)
      getCtor().newInstance(message) as java.lang.Exception
      else
      getCtor().newInstance(message, inner) as java.lang.Exception



      fun Constructor<out Any>.makeAccessible(): Constructor<out Any>
      this.isAccessible = true
      return this



      val dynamicExceptionSourceCode: String = """
      public class NameException extends java.lang.Exception
      public NameException(java.lang.String message)
      super(message);

      public NameException(java.lang.String message, java.lang.Throwable inner)
      super(message, inner);


      """.trimIndent()

      class SourceCodeJavaFileObject : SimpleJavaFileObject
      private val sourceCode: CharSequence

      constructor(className: String, sourceCode: CharSequence) :
      super(
      URI.create("string:///" + className.replace('.', '/') + JavaFileObject.Kind.SOURCE.extension),
      JavaFileObject.Kind.SOURCE
      )
      this.sourceCode = sourceCode


      override fun getCharContent(ignoreEncodingErrors: Boolean): CharSequence
      return sourceCode




      The string formatting is done with a string extension that can replace patterns. I based it on my C# formatter. However, it's simpler because it doesn't not support value formatting.



      import java.util.*

      fun String.smartFormat(values: TreeMap<String, String>): String
      val regex = Regex("""(?<name>[a-z][a-z0-9_.-]*)""", RegexOption.IGNORE_CASE)
      return regex.replace(this)
      var key = it.groups["name"]?.value
      if (values.containsKey(key)) values[key]!! else it.value





      Is there anything that can be simplified or made even cleaner?







      java exception kotlin compiler






      share|improve this question













      share|improve this question











      share|improve this question




      share|improve this question










      asked 27 mins ago









      t3chb0tt3chb0t

      35.4k754127




      35.4k754127




















          0






          active

          oldest

          votes












          Your Answer






          StackExchange.ifUsing("editor", function ()
          StackExchange.using("externalEditor", function ()
          StackExchange.using("snippets", function ()
          StackExchange.snippets.init();
          );
          );
          , "code-snippets");

          StackExchange.ready(function()
          var channelOptions =
          tags: "".split(" "),
          id: "196"
          ;
          initTagRenderer("".split(" "), "".split(" "), channelOptions);

          StackExchange.using("externalEditor", function()
          // Have to fire editor after snippets, if snippets enabled
          if (StackExchange.settings.snippets.snippetsEnabled)
          StackExchange.using("snippets", function()
          createEditor();
          );

          else
          createEditor();

          );

          function createEditor()
          StackExchange.prepareEditor(
          heartbeatType: 'answer',
          autoActivateHeartbeat: false,
          convertImagesToLinks: false,
          noModals: true,
          showLowRepImageUploadWarning: true,
          reputationToPostImages: null,
          bindNavPrevention: true,
          postfix: "",
          imageUploader:
          brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
          contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
          allowUrls: true
          ,
          onDemand: true,
          discardSelector: ".discard-answer"
          ,immediatelyShowMarkdownHelp:true
          );



          );













          draft saved

          draft discarded


















          StackExchange.ready(
          function ()
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f217885%2fcompiling-and-throwing-simple-dynamic-excepitons-at-runtime-for-jvm%23new-answer', 'question_page');

          );

          Post as a guest















          Required, but never shown

























          0






          active

          oldest

          votes








          0






          active

          oldest

          votes









          active

          oldest

          votes






          active

          oldest

          votes















          draft saved

          draft discarded
















































          Thanks for contributing an answer to Code Review Stack Exchange!


          • Please be sure to answer the question. Provide details and share your research!

          But avoid


          • Asking for help, clarification, or responding to other answers.

          • Making statements based on opinion; back them up with references or personal experience.

          Use MathJax to format equations. MathJax reference.


          To learn more, see our tips on writing great answers.




          draft saved


          draft discarded














          StackExchange.ready(
          function ()
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f217885%2fcompiling-and-throwing-simple-dynamic-excepitons-at-runtime-for-jvm%23new-answer', 'question_page');

          );

          Post as a guest















          Required, but never shown





















































          Required, but never shown














          Required, but never shown












          Required, but never shown







          Required, but never shown

































          Required, but never shown














          Required, but never shown












          Required, but never shown







          Required, but never shown







          Popular posts from this blog

          名間水力發電廠 目录 沿革 設施 鄰近設施 註釋 外部連結 导航菜单23°50′10″N 120°42′41″E / 23.83611°N 120.71139°E / 23.83611; 120.7113923°50′10″N 120°42′41″E / 23.83611°N 120.71139°E / 23.83611; 120.71139計畫概要原始内容臺灣第一座BOT 模式開發的水力發電廠-名間水力電廠名間水力發電廠 水利署首件BOT案原始内容《小檔案》名間電廠 首座BOT水力發電廠原始内容名間電廠BOT - 經濟部水利署中區水資源局

          Prove that NP is closed under karp reduction?Space(n) not closed under Karp reductions - what about NTime(n)?Class P is closed under rotation?Prove or disprove that $NL$ is closed under polynomial many-one reductions$mathbfNC_2$ is closed under log-space reductionOn Karp reductionwhen can I know if a class (complexity) is closed under reduction (cook/karp)Check if class $PSPACE$ is closed under polyonomially space reductionIs NPSPACE also closed under polynomial-time reduction and under log-space reduction?Prove PSPACE is closed under complement?Prove PSPACE is closed under union?

          Is my guitar’s action too high? Announcing the arrival of Valued Associate #679: Cesar Manara Planned maintenance scheduled April 23, 2019 at 23:30 UTC (7:30pm US/Eastern)Strings too stiff on a recently purchased acoustic guitar | Cort AD880CEIs the action of my guitar really high?Μy little finger is too weak to play guitarWith guitar, how long should I give my fingers to strengthen / callous?When playing a fret the guitar sounds mutedPlaying (Barre) chords up the guitar neckI think my guitar strings are wound too tight and I can't play barre chordsF barre chord on an SG guitarHow to find to the right strings of a barre chord by feel?High action on higher fret on my steel acoustic guitar