Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

No logging framework implementation when enabling proguard on Android #126

Closed
grill2010 opened this issue Nov 23, 2019 · 14 comments
Closed

No logging framework implementation when enabling proguard on Android #126

grill2010 opened this issue Nov 23, 2019 · 14 comments
Labels
bug

Comments

@grill2010
Copy link

@grill2010 grill2010 commented Nov 23, 2019

Hi, I'm using tinylog version 2.0.0 on Android and it worked great. However I recently released my new app and I found out that the log file never gets created. So I started to investigate the issue. What I found out is that as soon as I enable proguard on my release build I receive following output on the logcat when I log something

LOGGER WARN: No logging framework implementation found in classpath. Add tinylog-impl.jar for outputting log entries.

My tinylog.properties file looks like this

writer=rolling file
writer.file=/data/data/test.grill.com/files/test_logs/test_log.txt
writer.level=info
writer.policies=size: 5mb
writer.format={date: HH:mm:ss.SSS} [{thread}] {level}:\n{message}

and it is located in my resources folder. Everything is working when I'm not enabling proguard. Are there some proguard rules which needs to be added when using tinylog with proguard?

Edit: seems that the ServiceLoader could not get anyResourses

classLoader.getResources(name);

returns an empty Enumeration when enabling proguard.

@pmwmedia pmwmedia added the question label Nov 25, 2019
@pmwmedia

This comment has been minimized.

Copy link
Owner

@pmwmedia pmwmedia commented Nov 25, 2019

The problem is that tinylog cannot find TinylogLoggingProvider and other classes, which are loaded by ServiceLoader, because Proguard renames all classes. If configure Proguard to keep all tinylog class names, logging should work again:

-keepnames public class org.tinylog.**
@grill2010

This comment has been minimized.

Copy link
Author

@grill2010 grill2010 commented Nov 25, 2019

Yes I know this, thank you for the information. I was already playing arround with

keepdirectories
keeppackagenames
keep enum
keep class
keep interface

but I didn't try yet with keepnames. Will try it when I'm at home. Thank you for the info.

@pmwmedia

This comment has been minimized.

Copy link
Owner

@pmwmedia pmwmedia commented Nov 25, 2019

@grill2010 Your are welcome! Please let me know if it works for you :-)

@grill2010

This comment has been minimized.

Copy link
Author

@grill2010 grill2010 commented Nov 25, 2019

Hmm, I'm not able to make it work. I think it should work but still I get the same error.
I know my proguard-rules files work because I have other rules in it which are working. I tried all sort of crazy rules now, here are a few examples

-keep class org.tinylog.** { ; }
-keep interface org.tinylog.
* { ; }
-keep enum org.tinylog.
* { *; }

-keepdirectories **tinylog**
-keepdirectories org.tinylog
-keepdirectories org.tinylog
-keepdirectories org.tinylog.**
-keepdirectories org.tinylog**

-keeppackagenames **tinylog**
-keeppackagenames org.tinylog
-keeppackagenames org.tinylog
-keeppackagenames org.tinylog.**
-keeppackagenames org.tinylog**

-keepnames class org.tinylog.*
-keepnames class org.tinylog.**
-keepnames class org.tinylog.** {*;}

-keepclasseswithmembers class org.tinylog.** {*;}

Nothing seems to be working, for now I do not have any more ideas.

@pmwmedia

This comment has been minimized.

Copy link
Owner

@pmwmedia pmwmedia commented Nov 25, 2019

@grill2010 Can you provide a minimal example project that reproduces the issue? I will analyze the cause.

@grill2010

This comment has been minimized.

Copy link
Author

@grill2010 grill2010 commented Nov 25, 2019

Sure, will try to provide some example project tomorrow.

@grill2010

This comment has been minimized.

Copy link
Author

@grill2010 grill2010 commented Nov 25, 2019

Faster than expected, here is a standard Android example with tinylog. I have included the pro guard rules and the build.gradle has minifying enabled. Same error occurs in this project.
TinyLogExample.zip

@grill2010

This comment has been minimized.

Copy link
Author

@grill2010 grill2010 commented Nov 26, 2019

I've analyzed the apk of my example project and I found out that when I build the project with proguard enabled the folder services in the META_INF/services directory is missing completely.

APK compiled with proguard
APK compiled without proguard

Any ideas why this happens? I didn't dig very much into the tinylog project yet so I have no clue yet why this happens.

@pmwmedia

This comment has been minimized.

Copy link
Owner

@pmwmedia pmwmedia commented Nov 27, 2019

@grill2010 The only way, I found to keep the META-INF/services directory is to use the -dontshrink rule.

With these ProGuard rules, tinylog works well with your example project.

##---------------Begin: tinylog  ----------
-dontshrink
-keepnames interface org.tinylog.**
-keepnames class * implements org.tinylog.**
##---------------End: tinylog  ----------

However, I don't like using the -dontshrink rule as it will lead to bigger APK files. Currently I'm looking for a way to bypass it.

@grill2010

This comment has been minimized.

Copy link
Author

@grill2010 grill2010 commented Nov 27, 2019

Okay I see, interesting. I was also looking around on the Internet and what I found is that there were a lot of problems with the META-INF/services directory in regard to include it in the build apk and it seems somehow the problem still persists. It is somehow related to proguard and not gradle. But of course using dontshrink option is not ideal like you said...

Edit: The dontshrink removes unused resources and proguard thinks that these resource files are somehow not needed and simply removes them. Maybe because they are not referenced directly in the code but are accessed via the ClassLoader. There must be a way to tell proguard to not remove this files. Another way would be to create a direct pseudo reference somewhere in the code so that proguard does not remove them, but I've not tested it yet.

@pmwmedia

This comment has been minimized.

Copy link
Owner

@pmwmedia pmwmedia commented Nov 27, 2019

I found a workaround to tell ProGuard to keep the service files:

protected void onCreate(Bundle savedInstanceState) {
    ServiceLoader.load(LoggingProvider.class);
    ServiceLoader.load(Writer.class);
    ServiceLoader.load(Policy.class);

    super.onCreate(savedInstanceState);

    Logger.error("Test output");

    ...
}

ProGuard rules:

##---------------Begin: tinylog  ----------
-keepnames interface org.tinylog.**
-keepnames class * implements org.tinylog.**
-keepclassmembers class * implements org.tinylog.** { <init>(...); }
##---------------End: tinylog  ----------

I plan to add these ServiceLoader calls directly in tinylog 2.1 to make logging with tinylog for Android developers much more convenient when using ProGuard.

For tinylog 3, I'm experimenting with a builder concept for instantiation of logging providers, writers, and policies. Then, even no ProGuard rules nor any workaround will be required for tinylog. This will also solve #127.

@grill2010

This comment has been minimized.

Copy link
Author

@grill2010 grill2010 commented Nov 27, 2019

Awesome. Thank you very much.
Suggestions for tinylog 3 sound good. If tinylog 2.0 is working correctly with the workaround that's good enough for me now. Looking forward to the next releases.

@pmwmedia pmwmedia added bug and removed question labels Nov 27, 2019
@pmwmedia

This comment has been minimized.

Copy link
Owner

@pmwmedia pmwmedia commented Nov 27, 2019

@grill2010 Could you test the attached JARs? They contain the workaround with the ServiceLoader.load() calls. You will only need the the three ProGuard rules from my last post.

tinylog-2.0-SNAPSHOT.zip

@grill2010

This comment has been minimized.

Copy link
Author

@grill2010 grill2010 commented Nov 27, 2019

Sure I will test it when I have time and will let you know what are the results.

@pmwmedia pmwmedia closed this Nov 30, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
2 participants
You can’t perform that action at this time.