Compiling and throwing simple dynamic exceptions 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 APIThrowing exceptions when validation failsUndo format when format disappearsImplementation of stackThrowing exceptions if there is not exactly one box retrievedGeneric Builder in Java needs annotation supportDeserializing a customly formatted stringCompiling and throwing simple dynamic excepitons at runtimeGetting single element or throwing one of two exceptions

Why these surprising proportionalities of integrals involving odd zeta values?

How to leave only the following strings?

How is an IPA symbol that lacks a name (e.g. ɲ) called?

Does the Pact of the Blade warlock feature allow me to customize the properties of the pact weapon I create?

What documents does someone with a long-term visa need to travel to another Schengen country?

Coin Game with infinite paradox

Why did Bronn offer to be Tyrion Lannister's champion in trial by combat?

Etymology of 見舞い

How to create a command for the "strange m" symbol in latex?

Why do people think Winterfell crypts is the safest place for women, children & old people?

Married in secret, can marital status in passport be changed at a later date?

Assertions In A Mock Callout Test

What were wait-states, and why was it only an issue for PCs?

What helicopter has the most rotor blades?

Like totally amazing interchangeable sister outfit accessory swapping or whatever

xkeyval -- read keys from file

Can a Wizard take the Magic Initiate feat and select spells from the Wizard list?

Determine the generator of an ideal of ring of integers

/bin/ls sorts differently than just ls

Protagonist's race is hidden - should I reveal it?

Is my guitar’s action too high?

Why did Israel vote against lifting the American embargo on Cuba?

Can I ask an author to send me his ebook?

Unix AIX passing variable and arguments to expect and spawn



Compiling and throwing simple dynamic exceptions 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 APIThrowing exceptions when validation failsUndo format when format disappearsImplementation of stackThrowing exceptions if there is not exactly one box retrievedGeneric Builder in Java needs annotation supportDeserializing a customly formatted stringCompiling and throwing simple dynamic excepitons at runtimeGetting single element or throwing one of two exceptions



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








1












$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?




Disclaimer: Please let's not make it about whether this utility is a good or bad practice. I've used it many projects already and it stands the test of being super-helpful and super-efficient. I can discuss it on Software Engineering if you'd like to know more but here I'm only interested in improving the code.










share|improve this question











$endgroup$











  • $begingroup$
    Given how easy and compact it is to create classes in Kotlin, I don't see the point for why you would want to do this. It will be completely impossible to catch those exceptions for example.
    $endgroup$
    – Simon Forsberg
    10 hours ago






  • 1




    $begingroup$
    @SimonForsberg true, it's easy but still, you have to write them. With this, you just throw exceptions... and catching them... mhmmm... I never knew why one would want to this ;-] It's for information purposes and for easier debugging, 99.99% there is nothing one can do about an exception but log it and break or repeat the operation so I see no value in catching anything but Exception.
    $endgroup$
    – t3chb0t
    10 hours ago







  • 5




    $begingroup$
    That's exactly what the message is for. You don't need to have one kind of exception for every possible method name that can be missing, just have one generic class for MethodNotSupported and use an appropriate message on it for all the details that you need to indicate what went wrong and how to reproduce it.
    $endgroup$
    – Simon Forsberg
    7 hours ago






  • 5




    $begingroup$
    If you don't want to catch specific exceptions, identified by their type, why would you want to introduce different exception types? Different messages will do the job of producing useful log entries. Your approach of invoking the compiler at runtime seems like a very complex solution to a problem that doesn't really exist.
    $endgroup$
    – Ralf Kleberhoff
    7 hours ago






  • 3




    $begingroup$
    @t3chb0t If all you've got is the name of the exception, then you are doing something else wrong. If you want maximum usefulness of the name of your exception, why don't your name your exception BackgroundNotFound_C_Users_t3chb0t_Desktop_filename_png ?
    $endgroup$
    – Simon Forsberg
    3 hours ago

















1












$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?




Disclaimer: Please let's not make it about whether this utility is a good or bad practice. I've used it many projects already and it stands the test of being super-helpful and super-efficient. I can discuss it on Software Engineering if you'd like to know more but here I'm only interested in improving the code.










share|improve this question











$endgroup$











  • $begingroup$
    Given how easy and compact it is to create classes in Kotlin, I don't see the point for why you would want to do this. It will be completely impossible to catch those exceptions for example.
    $endgroup$
    – Simon Forsberg
    10 hours ago






  • 1




    $begingroup$
    @SimonForsberg true, it's easy but still, you have to write them. With this, you just throw exceptions... and catching them... mhmmm... I never knew why one would want to this ;-] It's for information purposes and for easier debugging, 99.99% there is nothing one can do about an exception but log it and break or repeat the operation so I see no value in catching anything but Exception.
    $endgroup$
    – t3chb0t
    10 hours ago







  • 5




    $begingroup$
    That's exactly what the message is for. You don't need to have one kind of exception for every possible method name that can be missing, just have one generic class for MethodNotSupported and use an appropriate message on it for all the details that you need to indicate what went wrong and how to reproduce it.
    $endgroup$
    – Simon Forsberg
    7 hours ago






  • 5




    $begingroup$
    If you don't want to catch specific exceptions, identified by their type, why would you want to introduce different exception types? Different messages will do the job of producing useful log entries. Your approach of invoking the compiler at runtime seems like a very complex solution to a problem that doesn't really exist.
    $endgroup$
    – Ralf Kleberhoff
    7 hours ago






  • 3




    $begingroup$
    @t3chb0t If all you've got is the name of the exception, then you are doing something else wrong. If you want maximum usefulness of the name of your exception, why don't your name your exception BackgroundNotFound_C_Users_t3chb0t_Desktop_filename_png ?
    $endgroup$
    – Simon Forsberg
    3 hours ago













1












1








1





$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?




Disclaimer: Please let's not make it about whether this utility is a good or bad practice. I've used it many projects already and it stands the test of being super-helpful and super-efficient. I can discuss it on Software Engineering if you'd like to know more but here I'm only interested in improving the code.










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?




Disclaimer: Please let's not make it about whether this utility is a good or bad practice. I've used it many projects already and it stands the test of being super-helpful and super-efficient. I can discuss it on Software Engineering if you'd like to know more but here I'm only interested in improving the code.







java exception kotlin compiler






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited 3 hours ago









Eric Duminil

2,1311613




2,1311613










asked 11 hours ago









t3chb0tt3chb0t

35.4k754127




35.4k754127











  • $begingroup$
    Given how easy and compact it is to create classes in Kotlin, I don't see the point for why you would want to do this. It will be completely impossible to catch those exceptions for example.
    $endgroup$
    – Simon Forsberg
    10 hours ago






  • 1




    $begingroup$
    @SimonForsberg true, it's easy but still, you have to write them. With this, you just throw exceptions... and catching them... mhmmm... I never knew why one would want to this ;-] It's for information purposes and for easier debugging, 99.99% there is nothing one can do about an exception but log it and break or repeat the operation so I see no value in catching anything but Exception.
    $endgroup$
    – t3chb0t
    10 hours ago







  • 5




    $begingroup$
    That's exactly what the message is for. You don't need to have one kind of exception for every possible method name that can be missing, just have one generic class for MethodNotSupported and use an appropriate message on it for all the details that you need to indicate what went wrong and how to reproduce it.
    $endgroup$
    – Simon Forsberg
    7 hours ago






  • 5




    $begingroup$
    If you don't want to catch specific exceptions, identified by their type, why would you want to introduce different exception types? Different messages will do the job of producing useful log entries. Your approach of invoking the compiler at runtime seems like a very complex solution to a problem that doesn't really exist.
    $endgroup$
    – Ralf Kleberhoff
    7 hours ago






  • 3




    $begingroup$
    @t3chb0t If all you've got is the name of the exception, then you are doing something else wrong. If you want maximum usefulness of the name of your exception, why don't your name your exception BackgroundNotFound_C_Users_t3chb0t_Desktop_filename_png ?
    $endgroup$
    – Simon Forsberg
    3 hours ago
















  • $begingroup$
    Given how easy and compact it is to create classes in Kotlin, I don't see the point for why you would want to do this. It will be completely impossible to catch those exceptions for example.
    $endgroup$
    – Simon Forsberg
    10 hours ago






  • 1




    $begingroup$
    @SimonForsberg true, it's easy but still, you have to write them. With this, you just throw exceptions... and catching them... mhmmm... I never knew why one would want to this ;-] It's for information purposes and for easier debugging, 99.99% there is nothing one can do about an exception but log it and break or repeat the operation so I see no value in catching anything but Exception.
    $endgroup$
    – t3chb0t
    10 hours ago







  • 5




    $begingroup$
    That's exactly what the message is for. You don't need to have one kind of exception for every possible method name that can be missing, just have one generic class for MethodNotSupported and use an appropriate message on it for all the details that you need to indicate what went wrong and how to reproduce it.
    $endgroup$
    – Simon Forsberg
    7 hours ago






  • 5




    $begingroup$
    If you don't want to catch specific exceptions, identified by their type, why would you want to introduce different exception types? Different messages will do the job of producing useful log entries. Your approach of invoking the compiler at runtime seems like a very complex solution to a problem that doesn't really exist.
    $endgroup$
    – Ralf Kleberhoff
    7 hours ago






  • 3




    $begingroup$
    @t3chb0t If all you've got is the name of the exception, then you are doing something else wrong. If you want maximum usefulness of the name of your exception, why don't your name your exception BackgroundNotFound_C_Users_t3chb0t_Desktop_filename_png ?
    $endgroup$
    – Simon Forsberg
    3 hours ago















$begingroup$
Given how easy and compact it is to create classes in Kotlin, I don't see the point for why you would want to do this. It will be completely impossible to catch those exceptions for example.
$endgroup$
– Simon Forsberg
10 hours ago




$begingroup$
Given how easy and compact it is to create classes in Kotlin, I don't see the point for why you would want to do this. It will be completely impossible to catch those exceptions for example.
$endgroup$
– Simon Forsberg
10 hours ago




1




1




$begingroup$
@SimonForsberg true, it's easy but still, you have to write them. With this, you just throw exceptions... and catching them... mhmmm... I never knew why one would want to this ;-] It's for information purposes and for easier debugging, 99.99% there is nothing one can do about an exception but log it and break or repeat the operation so I see no value in catching anything but Exception.
$endgroup$
– t3chb0t
10 hours ago





$begingroup$
@SimonForsberg true, it's easy but still, you have to write them. With this, you just throw exceptions... and catching them... mhmmm... I never knew why one would want to this ;-] It's for information purposes and for easier debugging, 99.99% there is nothing one can do about an exception but log it and break or repeat the operation so I see no value in catching anything but Exception.
$endgroup$
– t3chb0t
10 hours ago





5




5




$begingroup$
That's exactly what the message is for. You don't need to have one kind of exception for every possible method name that can be missing, just have one generic class for MethodNotSupported and use an appropriate message on it for all the details that you need to indicate what went wrong and how to reproduce it.
$endgroup$
– Simon Forsberg
7 hours ago




$begingroup$
That's exactly what the message is for. You don't need to have one kind of exception for every possible method name that can be missing, just have one generic class for MethodNotSupported and use an appropriate message on it for all the details that you need to indicate what went wrong and how to reproduce it.
$endgroup$
– Simon Forsberg
7 hours ago




5




5




$begingroup$
If you don't want to catch specific exceptions, identified by their type, why would you want to introduce different exception types? Different messages will do the job of producing useful log entries. Your approach of invoking the compiler at runtime seems like a very complex solution to a problem that doesn't really exist.
$endgroup$
– Ralf Kleberhoff
7 hours ago




$begingroup$
If you don't want to catch specific exceptions, identified by their type, why would you want to introduce different exception types? Different messages will do the job of producing useful log entries. Your approach of invoking the compiler at runtime seems like a very complex solution to a problem that doesn't really exist.
$endgroup$
– Ralf Kleberhoff
7 hours ago




3




3




$begingroup$
@t3chb0t If all you've got is the name of the exception, then you are doing something else wrong. If you want maximum usefulness of the name of your exception, why don't your name your exception BackgroundNotFound_C_Users_t3chb0t_Desktop_filename_png ?
$endgroup$
– Simon Forsberg
3 hours ago




$begingroup$
@t3chb0t If all you've got is the name of the exception, then you are doing something else wrong. If you want maximum usefulness of the name of your exception, why don't your name your exception BackgroundNotFound_C_Users_t3chb0t_Desktop_filename_png ?
$endgroup$
– Simon Forsberg
3 hours ago










2 Answers
2






active

oldest

votes


















12












$begingroup$


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




Yes, don't invoke the Java compiler at runtime.



From your examples in a comment:



DynamicException.Create($"ExtractMethodName(memberName)}NotSupported", ...)



From an example on your earlier post (in C#)




throw ("SettingNotFoundException", $"Setting fullName.ToString().QuoteWith("'") not found.").ToDynamicException())



public BackgroundImageNotFoundException(string fileName) : base($"Where is the 'fileName' image?")




Replace these with:



  • throw new MethodNotSupported(extractMethodName(memberName))

  • throw new UnsupportedOperationError(extractMethodName(memberName))

  • throw new IllegalStateException("Setting '" + fullName + "' not found")

  • throw new FileNotFoundException(fileName)

If you look at the subclasses of Java's Exception or RuntimeException (many of which also has a Kotlin version) you can probably find an already existing exception that does what you need, and you just need to add a message to it.



In a chat message related to your C# post you wrote:




In order to be able to track down a bug you need two pieces of information: The name of the exception and a message. With a generic exception I could just throw an Exception but the name of the exception should already be strong enough to tell what caused it, the message is just a hint.



You should already know what happend by not even reading the message.




I completely disagree with this. The message is not just a hint. To understand fully what happened and how to reproduce it you need to read the message.




As an extra bonus, here's how you define exceptions easily in Kotlin, and the approach I would recommend:



class MyException(message: String) : Exception(message)
class SomeOtherException(message: String) : Exception(message)
class UsefulException(message: String) : Exception(message)
class AnotherUsefulException(message: String) : Exception(message)


Please note that all this can be defined in the same file.






share|improve this answer











$endgroup$








  • 3




    $begingroup$
    Disclaimer: This answer was written 10 seconds before the question was edited and a disclaimer was added. Either way, I still stand by this answer and I believe that your current approach is not good practice and adds unnecessary complexity.
    $endgroup$
    – Simon Forsberg
    6 hours ago










  • $begingroup$
    I'll give you a +1 because I always do it as a gesture of appriciation for every replay but I still don't agree with this and I stand to the usefullness of my solution.
    $endgroup$
    – t3chb0t
    6 hours ago







  • 2




    $begingroup$
    The disclaimer on the question is counterproductive. This question still deserves a frame challenge whether the author wants one or not. Doing so is really the only appropriate answer. +1
    $endgroup$
    – jpmc26
    2 hours ago



















2












$begingroup$

Setting isAccessible to true



You seem to be always settings isAccessible to true. This is only needed if you are accessing methods outside their "access modifier", for example if you are trying to access a private method from another class.



Since you are only calling public methods (on public classes), this is not required.



Support for javax.tools is not for all android versions



You are using packages from javax.tools, this is not available on every android version, see the following SO question: NoClassDefFoundException when using javax.tools package, make sure to properly test on the oldest android version you are targetting.



To avoid these packages, manually define a class using byte arrays, and load that instead of the output of the compilation






share|improve this answer









$endgroup$













    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-exceptions-at-runtime-for-jvm%23new-answer', 'question_page');

    );

    Post as a guest















    Required, but never shown

























    2 Answers
    2






    active

    oldest

    votes








    2 Answers
    2






    active

    oldest

    votes









    active

    oldest

    votes






    active

    oldest

    votes









    12












    $begingroup$


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




    Yes, don't invoke the Java compiler at runtime.



    From your examples in a comment:



    DynamicException.Create($"ExtractMethodName(memberName)}NotSupported", ...)



    From an example on your earlier post (in C#)




    throw ("SettingNotFoundException", $"Setting fullName.ToString().QuoteWith("'") not found.").ToDynamicException())



    public BackgroundImageNotFoundException(string fileName) : base($"Where is the 'fileName' image?")




    Replace these with:



    • throw new MethodNotSupported(extractMethodName(memberName))

    • throw new UnsupportedOperationError(extractMethodName(memberName))

    • throw new IllegalStateException("Setting '" + fullName + "' not found")

    • throw new FileNotFoundException(fileName)

    If you look at the subclasses of Java's Exception or RuntimeException (many of which also has a Kotlin version) you can probably find an already existing exception that does what you need, and you just need to add a message to it.



    In a chat message related to your C# post you wrote:




    In order to be able to track down a bug you need two pieces of information: The name of the exception and a message. With a generic exception I could just throw an Exception but the name of the exception should already be strong enough to tell what caused it, the message is just a hint.



    You should already know what happend by not even reading the message.




    I completely disagree with this. The message is not just a hint. To understand fully what happened and how to reproduce it you need to read the message.




    As an extra bonus, here's how you define exceptions easily in Kotlin, and the approach I would recommend:



    class MyException(message: String) : Exception(message)
    class SomeOtherException(message: String) : Exception(message)
    class UsefulException(message: String) : Exception(message)
    class AnotherUsefulException(message: String) : Exception(message)


    Please note that all this can be defined in the same file.






    share|improve this answer











    $endgroup$








    • 3




      $begingroup$
      Disclaimer: This answer was written 10 seconds before the question was edited and a disclaimer was added. Either way, I still stand by this answer and I believe that your current approach is not good practice and adds unnecessary complexity.
      $endgroup$
      – Simon Forsberg
      6 hours ago










    • $begingroup$
      I'll give you a +1 because I always do it as a gesture of appriciation for every replay but I still don't agree with this and I stand to the usefullness of my solution.
      $endgroup$
      – t3chb0t
      6 hours ago







    • 2




      $begingroup$
      The disclaimer on the question is counterproductive. This question still deserves a frame challenge whether the author wants one or not. Doing so is really the only appropriate answer. +1
      $endgroup$
      – jpmc26
      2 hours ago
















    12












    $begingroup$


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




    Yes, don't invoke the Java compiler at runtime.



    From your examples in a comment:



    DynamicException.Create($"ExtractMethodName(memberName)}NotSupported", ...)



    From an example on your earlier post (in C#)




    throw ("SettingNotFoundException", $"Setting fullName.ToString().QuoteWith("'") not found.").ToDynamicException())



    public BackgroundImageNotFoundException(string fileName) : base($"Where is the 'fileName' image?")




    Replace these with:



    • throw new MethodNotSupported(extractMethodName(memberName))

    • throw new UnsupportedOperationError(extractMethodName(memberName))

    • throw new IllegalStateException("Setting '" + fullName + "' not found")

    • throw new FileNotFoundException(fileName)

    If you look at the subclasses of Java's Exception or RuntimeException (many of which also has a Kotlin version) you can probably find an already existing exception that does what you need, and you just need to add a message to it.



    In a chat message related to your C# post you wrote:




    In order to be able to track down a bug you need two pieces of information: The name of the exception and a message. With a generic exception I could just throw an Exception but the name of the exception should already be strong enough to tell what caused it, the message is just a hint.



    You should already know what happend by not even reading the message.




    I completely disagree with this. The message is not just a hint. To understand fully what happened and how to reproduce it you need to read the message.




    As an extra bonus, here's how you define exceptions easily in Kotlin, and the approach I would recommend:



    class MyException(message: String) : Exception(message)
    class SomeOtherException(message: String) : Exception(message)
    class UsefulException(message: String) : Exception(message)
    class AnotherUsefulException(message: String) : Exception(message)


    Please note that all this can be defined in the same file.






    share|improve this answer











    $endgroup$








    • 3




      $begingroup$
      Disclaimer: This answer was written 10 seconds before the question was edited and a disclaimer was added. Either way, I still stand by this answer and I believe that your current approach is not good practice and adds unnecessary complexity.
      $endgroup$
      – Simon Forsberg
      6 hours ago










    • $begingroup$
      I'll give you a +1 because I always do it as a gesture of appriciation for every replay but I still don't agree with this and I stand to the usefullness of my solution.
      $endgroup$
      – t3chb0t
      6 hours ago







    • 2




      $begingroup$
      The disclaimer on the question is counterproductive. This question still deserves a frame challenge whether the author wants one or not. Doing so is really the only appropriate answer. +1
      $endgroup$
      – jpmc26
      2 hours ago














    12












    12








    12





    $begingroup$


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




    Yes, don't invoke the Java compiler at runtime.



    From your examples in a comment:



    DynamicException.Create($"ExtractMethodName(memberName)}NotSupported", ...)



    From an example on your earlier post (in C#)




    throw ("SettingNotFoundException", $"Setting fullName.ToString().QuoteWith("'") not found.").ToDynamicException())



    public BackgroundImageNotFoundException(string fileName) : base($"Where is the 'fileName' image?")




    Replace these with:



    • throw new MethodNotSupported(extractMethodName(memberName))

    • throw new UnsupportedOperationError(extractMethodName(memberName))

    • throw new IllegalStateException("Setting '" + fullName + "' not found")

    • throw new FileNotFoundException(fileName)

    If you look at the subclasses of Java's Exception or RuntimeException (many of which also has a Kotlin version) you can probably find an already existing exception that does what you need, and you just need to add a message to it.



    In a chat message related to your C# post you wrote:




    In order to be able to track down a bug you need two pieces of information: The name of the exception and a message. With a generic exception I could just throw an Exception but the name of the exception should already be strong enough to tell what caused it, the message is just a hint.



    You should already know what happend by not even reading the message.




    I completely disagree with this. The message is not just a hint. To understand fully what happened and how to reproduce it you need to read the message.




    As an extra bonus, here's how you define exceptions easily in Kotlin, and the approach I would recommend:



    class MyException(message: String) : Exception(message)
    class SomeOtherException(message: String) : Exception(message)
    class UsefulException(message: String) : Exception(message)
    class AnotherUsefulException(message: String) : Exception(message)


    Please note that all this can be defined in the same file.






    share|improve this answer











    $endgroup$




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




    Yes, don't invoke the Java compiler at runtime.



    From your examples in a comment:



    DynamicException.Create($"ExtractMethodName(memberName)}NotSupported", ...)



    From an example on your earlier post (in C#)




    throw ("SettingNotFoundException", $"Setting fullName.ToString().QuoteWith("'") not found.").ToDynamicException())



    public BackgroundImageNotFoundException(string fileName) : base($"Where is the 'fileName' image?")




    Replace these with:



    • throw new MethodNotSupported(extractMethodName(memberName))

    • throw new UnsupportedOperationError(extractMethodName(memberName))

    • throw new IllegalStateException("Setting '" + fullName + "' not found")

    • throw new FileNotFoundException(fileName)

    If you look at the subclasses of Java's Exception or RuntimeException (many of which also has a Kotlin version) you can probably find an already existing exception that does what you need, and you just need to add a message to it.



    In a chat message related to your C# post you wrote:




    In order to be able to track down a bug you need two pieces of information: The name of the exception and a message. With a generic exception I could just throw an Exception but the name of the exception should already be strong enough to tell what caused it, the message is just a hint.



    You should already know what happend by not even reading the message.




    I completely disagree with this. The message is not just a hint. To understand fully what happened and how to reproduce it you need to read the message.




    As an extra bonus, here's how you define exceptions easily in Kotlin, and the approach I would recommend:



    class MyException(message: String) : Exception(message)
    class SomeOtherException(message: String) : Exception(message)
    class UsefulException(message: String) : Exception(message)
    class AnotherUsefulException(message: String) : Exception(message)


    Please note that all this can be defined in the same file.







    share|improve this answer














    share|improve this answer



    share|improve this answer








    edited 3 hours ago

























    answered 6 hours ago









    Simon ForsbergSimon Forsberg

    49k7130288




    49k7130288







    • 3




      $begingroup$
      Disclaimer: This answer was written 10 seconds before the question was edited and a disclaimer was added. Either way, I still stand by this answer and I believe that your current approach is not good practice and adds unnecessary complexity.
      $endgroup$
      – Simon Forsberg
      6 hours ago










    • $begingroup$
      I'll give you a +1 because I always do it as a gesture of appriciation for every replay but I still don't agree with this and I stand to the usefullness of my solution.
      $endgroup$
      – t3chb0t
      6 hours ago







    • 2




      $begingroup$
      The disclaimer on the question is counterproductive. This question still deserves a frame challenge whether the author wants one or not. Doing so is really the only appropriate answer. +1
      $endgroup$
      – jpmc26
      2 hours ago













    • 3




      $begingroup$
      Disclaimer: This answer was written 10 seconds before the question was edited and a disclaimer was added. Either way, I still stand by this answer and I believe that your current approach is not good practice and adds unnecessary complexity.
      $endgroup$
      – Simon Forsberg
      6 hours ago










    • $begingroup$
      I'll give you a +1 because I always do it as a gesture of appriciation for every replay but I still don't agree with this and I stand to the usefullness of my solution.
      $endgroup$
      – t3chb0t
      6 hours ago







    • 2




      $begingroup$
      The disclaimer on the question is counterproductive. This question still deserves a frame challenge whether the author wants one or not. Doing so is really the only appropriate answer. +1
      $endgroup$
      – jpmc26
      2 hours ago








    3




    3




    $begingroup$
    Disclaimer: This answer was written 10 seconds before the question was edited and a disclaimer was added. Either way, I still stand by this answer and I believe that your current approach is not good practice and adds unnecessary complexity.
    $endgroup$
    – Simon Forsberg
    6 hours ago




    $begingroup$
    Disclaimer: This answer was written 10 seconds before the question was edited and a disclaimer was added. Either way, I still stand by this answer and I believe that your current approach is not good practice and adds unnecessary complexity.
    $endgroup$
    – Simon Forsberg
    6 hours ago












    $begingroup$
    I'll give you a +1 because I always do it as a gesture of appriciation for every replay but I still don't agree with this and I stand to the usefullness of my solution.
    $endgroup$
    – t3chb0t
    6 hours ago





    $begingroup$
    I'll give you a +1 because I always do it as a gesture of appriciation for every replay but I still don't agree with this and I stand to the usefullness of my solution.
    $endgroup$
    – t3chb0t
    6 hours ago





    2




    2




    $begingroup$
    The disclaimer on the question is counterproductive. This question still deserves a frame challenge whether the author wants one or not. Doing so is really the only appropriate answer. +1
    $endgroup$
    – jpmc26
    2 hours ago





    $begingroup$
    The disclaimer on the question is counterproductive. This question still deserves a frame challenge whether the author wants one or not. Doing so is really the only appropriate answer. +1
    $endgroup$
    – jpmc26
    2 hours ago














    2












    $begingroup$

    Setting isAccessible to true



    You seem to be always settings isAccessible to true. This is only needed if you are accessing methods outside their "access modifier", for example if you are trying to access a private method from another class.



    Since you are only calling public methods (on public classes), this is not required.



    Support for javax.tools is not for all android versions



    You are using packages from javax.tools, this is not available on every android version, see the following SO question: NoClassDefFoundException when using javax.tools package, make sure to properly test on the oldest android version you are targetting.



    To avoid these packages, manually define a class using byte arrays, and load that instead of the output of the compilation






    share|improve this answer









    $endgroup$

















      2












      $begingroup$

      Setting isAccessible to true



      You seem to be always settings isAccessible to true. This is only needed if you are accessing methods outside their "access modifier", for example if you are trying to access a private method from another class.



      Since you are only calling public methods (on public classes), this is not required.



      Support for javax.tools is not for all android versions



      You are using packages from javax.tools, this is not available on every android version, see the following SO question: NoClassDefFoundException when using javax.tools package, make sure to properly test on the oldest android version you are targetting.



      To avoid these packages, manually define a class using byte arrays, and load that instead of the output of the compilation






      share|improve this answer









      $endgroup$















        2












        2








        2





        $begingroup$

        Setting isAccessible to true



        You seem to be always settings isAccessible to true. This is only needed if you are accessing methods outside their "access modifier", for example if you are trying to access a private method from another class.



        Since you are only calling public methods (on public classes), this is not required.



        Support for javax.tools is not for all android versions



        You are using packages from javax.tools, this is not available on every android version, see the following SO question: NoClassDefFoundException when using javax.tools package, make sure to properly test on the oldest android version you are targetting.



        To avoid these packages, manually define a class using byte arrays, and load that instead of the output of the compilation






        share|improve this answer









        $endgroup$



        Setting isAccessible to true



        You seem to be always settings isAccessible to true. This is only needed if you are accessing methods outside their "access modifier", for example if you are trying to access a private method from another class.



        Since you are only calling public methods (on public classes), this is not required.



        Support for javax.tools is not for all android versions



        You are using packages from javax.tools, this is not available on every android version, see the following SO question: NoClassDefFoundException when using javax.tools package, make sure to properly test on the oldest android version you are targetting.



        To avoid these packages, manually define a class using byte arrays, and load that instead of the output of the compilation







        share|improve this answer












        share|improve this answer



        share|improve this answer










        answered 3 hours ago









        FerrybigFerrybig

        1,222614




        1,222614



























            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-exceptions-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

            Ружовы пелікан Змест Знешні выгляд | Пашырэнне | Асаблівасці біялогіі | Літаратура | НавігацыяДагледжаная версіяправерана1 зменаДагледжаная версіяправерана1 змена/ 22697590 Сістэматыкана ВіківідахВыявына Вікісховішчы174693363011049382

            ValueError: Error when checking input: expected conv2d_13_input to have shape (3, 150, 150) but got array with shape (150, 150, 3)2019 Community Moderator ElectionError when checking : expected dense_1_input to have shape (None, 5) but got array with shape (200, 1)Error 'Expected 2D array, got 1D array instead:'ValueError: Error when checking input: expected lstm_41_input to have 3 dimensions, but got array with shape (40000,100)ValueError: Error when checking target: expected dense_1 to have shape (7,) but got array with shape (1,)ValueError: Error when checking target: expected dense_2 to have shape (1,) but got array with shape (0,)Keras exception: ValueError: Error when checking input: expected conv2d_1_input to have shape (150, 150, 3) but got array with shape (256, 256, 3)Steps taking too long to completewhen checking input: expected dense_1_input to have shape (13328,) but got array with shape (317,)ValueError: Error when checking target: expected dense_3 to have shape (None, 1) but got array with shape (7715, 40000)Keras exception: Error when checking input: expected dense_input to have shape (2,) but got array with shape (1,)

            Illegal assignment from SObject to ContactFetching String, Id from Map - Illegal Assignment Id to Field / ObjectError: Compile Error: Illegal assignment from String to BooleanError: List has no rows for assignment to SObjectError on Test Class - System.QueryException: List has no rows for assignment to SObjectRemote action problemDML requires SObject or SObject list type error“Illegal assignment from List to List”Test Class Fail: Batch Class: System.QueryException: List has no rows for assignment to SObjectMapping to a user'List has no rows for assignment to SObject' Mystery