-
Notifications
You must be signed in to change notification settings - Fork 120
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
Retrieving a SmallRyeConfig instance fails on Android #1057
Comments
Yes, please provide a reproducer. Thanks! |
Propably the root of the problem is in principle not smallrye config itself, but the fact that Android is missing the jar file provider for java.nio.file, so using |
Unfortunately, I need to update my version of IntelliJ does not support your reproducer, so I couldn't run it. I did create one Android project from a template, added SR Config and it seemed to work. Can you please, paste me the stacktrace you get? Thanks! |
I repeated your steps an I confirm that the problem does not appear in an new Android Start Project, when you retrieve a configuration only, as long as there is no microprofile-config.properties file. To reproduce, please switch in the Project pane from "Android" to "Project" and add a folder app/src/main/resources/META-INF/microprofile-config.properties Just for now I added this info and the stack trace to the readme in the github expample project caberger/android-jetpack-compose-smallrye-config There you can also find details about how to create the project and reproduce the problem. |
I did add a file, but apparently, it was not being picked up. I can now see the stacktrace. Not sure what we can do... it is unfortunate that Android does not support nio jar, but I can try to figure out if it is possible to achieve the behaviour we have right now and get rid of the filesystem jar call. |
Well, I think the Problem is in What about changing consumeAsPaths to consumeAsInputStreams, like in the following: public class MainActivity extends ComponentActivity {
private static final String TAG = MainActivity.class.getName();
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
try {
consumeAsInputStreams(getClass().getClassLoader(), "META-INF/microprofile-config.properties", inputStream -> {
var properties = new Properties();
try {
properties.load(inputStream);
// TODO: use these properties for config
properties.forEach((key, value) -> Log.i(TAG, String.format("%s -> %s", key, value))); // <-- remove this
} catch (IOException e) {
throw new RuntimeException(e);
}
});
} catch (IOException e) {
throw new RuntimeException(e);
}
//...
}
void consumeAsInputStreams(ClassLoader cl, String resource, Consumer<InputStream> consumer) throws IOException {
final var resources = cl.getResources(resource);
while (resources.hasMoreElements()) {
final var res = resources.nextElement();
try (var is = res.openStream()) {
consumer.accept(is);
}
}
}
} It works on Android, the full app is here. ouch, I understand to change this would touch very stable, well tested and often used code ... |
Yes, but it does it, because the URI is from a We also support passing a Finally, we cannot rely on the CL
Correct. The URL format is not the issue, but Android not supporting the |
Yes, I absolutely agree to your arguments. It is hard to touch that code.
So maybe it is better to prepare those things first and only after that touch the good and reliable existing CL/FileSystem code. |
The coverage should be a bit higher: Not all the tests are inside the
Yes, we would need to remove
Feel free to add additional tests. You can find most of the testes about the classpath loading here: https://github.com/smallrye/smallrye-config/blob/27b00d0f9f61969777cf72b8bcddc5bdce80d0c2/testsuite/extra/src/test/java/io/smallrye/config/test/location/PropertiesLocationTest.java. |
On Android the following Statement crashes:
with a ProviderNotFoundException.
Propably the reason is that io.smallrye.config.AbstractLocationConfigSourceLoader does not pass the ClassLoader that has been passed in to consumeAsPaths(...) and so ClassPathUtils::processAsPath uses
(ClassLoader) null
as argument instead.In addition to that AbstractLocationConfigSourceLoader::tryClassPath() does not catch the ProviderNotFoundException, which is a RunTimeException, not an IOException.
SmallRye config works perfectly on Android when I use a self-coded ConfigSourceProvider, which does nothing more than use getClass().getClassLoader() to load the property files.
Doing that SmallRye Config can perfectly be used in Android with java 17 by adding
implementation("io.smallrye.config:smallrye-config:3.4.4")
to build.gradle.kt, and adding aresources/
folder tosrc/main
with e.g. an application.properties and a META-INF/microprofile-config.properties file.If you need an example Android App to reproduce the problem please tell me.
After fixing the above small Problem SmallRye config would be a perfect microprofile config implementation also for Android , in my opinion the best and most mature way to configure Android Apps.
The text was updated successfully, but these errors were encountered: