So, I want to get rid of those kotlin null-checks. I already have added the compiler flags -Xno-call-assertions -Xno-receiver-assertions -Xno-param-assertions, which got rid of most of them.
When I decompile the compiled jar, this TypeCastException is still there, which I would like to get rid also.
So I’m looking for a compiler option or a proguard rule to remove it.
This is the decompiled piece of code:
final Object value = SomeStaticClass.getValue();
if (value == null) {
throw new TypeCastException("null cannot be cast to non-null type kotlin.Int");
}
final int myValName = (int)value;
Edit: There are actually way more similar checks, which check for null or type safety. Is it possible to disable all of that?
Can you describe why you’re doing this? If there is no explicit compiler argument to disable such assertions, I doubt that it can be done, save for forking your custom compiler.
My final jar will be used as a plugin in the java environment. The kotlin stdlib would properly collide with other plugins using kotlin (they are all in the same classpath). That’s why I am using Proguard to obfuscate the stdlib. I also remove all unnceccesary kotlin module files.
So That’s why I started cleaning up kotlin leftover stuff.
My main Reason, why I started to remove the null checks is to prevent leaking var names (There are hardcoded strings with the name of the variable in the code). I haven’t looked deeper, and I’m afraid that there might be more of those leaks. I don’t like it to only remove half of the checks (either all or none).
Why are those checks even in the code? There would be an java exception anyways.
The way to deal with this issue is to use classloaders. Normally the plugin container would do this for you already, but otherwise you can have a two-stage plugin. One that is loaded with the container loader and uses its own classloader to load all internal bits. Classloaders can be a bit mindboggling, but are very powerful for these kinds of issues.
I don’t know how it deals with that. But it is possible to access methods from other plugins (with is needed, some plugins hook into the functionality of the program), so I assume the kotlin stdlib would collide.
That would a bit overkill, plus I would need to access another plugin. It seems, like using Proguard to obfuscate or repack the classes would be a better idea.
Basically, you are going towards something resembling OSGI. But servlet containers such as tomcat also use this to isolate applications. I’m not saying it is very easy, and using frameworks can help. Key is that the API classes for the plugin (the interface the plugin implements as well as api’s it uses to interact with the rest) are loaded by the parent class loader.
In case of the Kotlin standard library, if you can guarantee the same version (or the highest version first), Java/the JVM will just load the first class and ignore the rest
The problem with “solutions” such as proguard is that they do not work well with reflection.
That’s just overkill. It’s a simple plugin, and it should not do something like that. It should just behave like a normal java plugin.
I cannot guarantee the same version. That’s the problem.
I don’t see why I should use Reflection to access the kotlin stdlib or my own plugin. I only can see barely see a use for Reflection in my own plugin. Maybe a custom eventhandler or filling a giant class with values. But Reflection doesn’t break instantly, only if I obfuscate everything or use a string to get the class (again, this shouldn’t be needed in a good project). If reflection is really needed, I could also only repack the kotlin classes. I can see no use at all for using Reflection in the kotlin stdlib, so I really don’t care about that.
So I made this small program, which generates a mapping for proguard. It will only affect kotlin classes. You need to add the rules -keep,allowshrinking,allowoptimization class ** and -applymapping Mapping.txt (Save program output as Mapping.txt). Link: KotlinMappingGenerator.kt · GitHub