question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Final Access Modifier Kotlin

See original GitHub issue

Hi,

First of very nice work. Nice UI very simple to go through. The alternatives are not even on par with this lib. This project could use some more recognition imho.

My question/bug: I don’t know if Recaf was only targeted for applications written in pure Java or not. However I’m facing an issue when trying to edit my access modifier of a Kotlin written .class

Consider the following Kotlin class

class Main {
	fun main(args: Array<String>) {
		println("Hello world from Kotlin")
	}
}

Since every class in Kotlin is final by default this Main class is too.
Recaf successfully reports this aswell.

screenshot from 2018-10-14 22-21-28

However upon removing the final modifier, saving it and trying to extend it

class SomeExtendedClass : Main() {
	fun someOtherMethod() {
			println("Some Other Message")
	}
}

Throws upon compilation:

SomeExtendedClass.kt:1:28: error: this type is final, so it cannot be inherited from class SomeExtendedClass : Main()

However the equivalent Java code does seem to do the trick.

final class Main {
	public static void main(String[] args) {
		System.out.println("Hello this is a Java world!");
	}
}

So first of, is it possible to edit the byte code from a Kotlin class? And if so how can I remove a final modifier and make it open/public

Issue Analytics

  • State:closed
  • Created 5 years ago
  • Comments:7 (5 by maintainers)

github_iconTop GitHub Comments

2reactions
timrijckaertcommented, Oct 26, 2018

No problem. I have tried your solution.

The @Metadata annotation is in the Visible annotations menu. However it is complete gibberish.

screenshot from 2018-10-26 10-59-51

I tried deleting it and exporting it. Whilst also setting the access to public

The JD-GUI decompiler now successfully says this class is a public class however in Android Studio the class is still final. I think deleting is not the solution. I probably need to edit the @Metadata annotation to tell it this class should be open

screenshot from 2018-10-26 11-00-36 screenshot from 2018-10-26 11-04-17

Edit I invalidated caches and restarted Android Studio. The class is public now.

Thanks a lot!

2reactions
andylizicommented, Oct 15, 2018

Kotlin uses an annotation called Metadata to store some extra information within the compiled class, and it’s used by the Kotlin compiler to determine a compiled Kotlin class’s actual modifier. Therefore, only change the modifiers specified in JVMS is not enough, you have to modify the data held in Metadata annotation too.

Here’s the difference between a final class’s metadata and a open class’s:

diff --git a/final.txt b/open.txt
index edede21..fd08b53 100644
--- a/final.txt
+++ b/open.txt
@@ -1,7 +1,7 @@
 @Metadata(
   mv={1, 1, 10},
   bv={1, 0, 2},
   k=1,
-  d1={"\u0000\u0012\n\u0002\u0018\u0002\n\u0002\u0010\u0000\n\u0002\b\u0002\n\u0002\u0010\u000e\n\u0000\u0018\u00002\u00020\u0001B\u0005\u00a2\u0006\u0002\u0010\u0002J\u0006\u0010\u0003\u001a\u00020\u0004\u00a8\u0006\u0005"},
+  d1={"\u0000\u0012\n\u0002\u0018\u0002\n\u0002\u0010\u0000\n\u0002\b\u0002\n\u0002\u0010\u000e\n\u0000\b\u0016\u0018\u00002\u00020\u0001B\u0005\u00a2\u0006\u0002\u0010\u0002J\u0006\u0010\u0003\u001a\u00020\u0004\u00a8\u0006\u0005"},
   d2={"LTest;", "", "()V", "foo", "", "Test"}
 )

According to the javadoc, d1 is written in a custom binary-like format, so it’s impractical to edit that directly using a text field. But after some Googling, I found out there’s an official library for reading and modifying the Kotlin metadata, so maybe it can help with this problem.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Visibility modifiers - Kotlin
There are four visibility modifiers in Kotlin: private , protected , internal , and public . The default visibility is public . On...
Read more >
Kotlin basics: inheritance modifiers. final, open, abstract and ...
The final modifier mark classes and methods as not allowed to be overridden. In Kotlin this is the default. This decision was made...
Read more >
Kotlin Visibility Modifiers - public, protected, internal, private
Visibility Modifiers are modifiers that when appended to a class/interface/property/function in Kotlin, would define where all it is visible and ...
Read more >
Kotlin Visibility Modifiers - GeeksforGeeks
In Kotlin, visibility modifiers are used to restrict the accessibility of classes, objects, interfaces, constructors, functions, properties, ...
Read more >
Visibility Modifiers in Kotlin - Baeldung
Visibility modifiers are used to determine what other elements of code have access to the element being modified. They apply to some different ......
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found