-
Notifications
You must be signed in to change notification settings - Fork 7
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
Inconsistency with builder and initial loader. Default resource loader does not use the System class loader? #141
Comments
Also this:
Should throw either EDIT that whole code block looks like duplication of stuff that Configuration.builder should do or know about: InputStream resource(String resourcePath, InitialLoader.Source source) {
InputStream is = null;
if (source == InitialLoader.Source.RESOURCE) {
is = resourceStream(resourcePath);
if (is != null) {
loadedResources.add("resource:" + resourcePath);
}
} else {
File file = new File(resourcePath);
if (file.exists()) {
try {
is = new FileInputStream(file);
loadedResources.add("file:" + resourcePath);
loadedFiles.add(file);
} catch (FileNotFoundException e) {
throw new IllegalStateException(e);
}
}
}
return is;
} Consequently when you use the Configuration.builder unlike the default loading: The source information is missing in That is I expect: var c = Configuration.builder().load("blah.properties").build();
assertEquals("resource:blah.properties",m c.entry("property_in_blah").orElseThrow().source()); But that is not the case. See #139 |
Not that it is super important but calling the ServiceLoader even just once is actually a significant cost. That is a better solution is actually to have private static ResourceLoader initialiseResourceLoader() {
return ServiceLoader.load(ResourceLoader.class)
.findFirst()
.orElseGet(DefaultResourceLoader::new);
}
private ConfigurationLog initLog() {
if (configurationLog == null) {
configurationLog = ServiceLoader.load(ConfigurationLog.class)
.findFirst()
.orElseGet(DefaultConfigurationLog::new);
}
return configurationLog;
}
private ModificationEventRunner initRunner() {
if (eventRunner == null) {
eventRunner = ServiceLoader.load(ModificationEventRunner.class)
.findFirst()
.orElseGet(CoreConfiguration.ForegroundEventRunner::new);
}
return eventRunner;
} |
Well now, I was actually thinking recently on how I could make things faster. It seems I've got my work cut out for me. |
@SentryMan Hey aren't you on vacation? Go back to enjoying that 😄 Also I owe it to you and @rbygrave to be tasked with things so let me know if you want me to do anything. |
…() as fallback This should be no change when using "normal" Config/Configuration but allows users of the ConfigurationBuilder to have this fallback to ClassLoader.getSystemResourceAsStream() when the resource is not found via the usual getClass().getResourceAsStream()
… fallback (#146) * #142 Use UncheckedIOException rather than IllegalStateException This improves consistency with other use of UncheckedIOException * #141 DefaultResourceLoader uses ClassLoader.getSystemResourceAsStream() as fallback This should be no change when using "normal" Config/Configuration but allows users of the ConfigurationBuilder to have this fallback to ClassLoader.getSystemResourceAsStream() when the resource is not found via the usual getClass().getResourceAsStream() * #141 Use inputStream as variable name
It does now due to #143
I don't know what you mean by that. Maybe you are referring to ClassLoader.getSystemResourceAsStream.
Yes that can be pushed down into the DefaultResourceLoader. Done now via #146
Done via #142
Ok, can have a look. Edit: Going with #147 for now, I'll have another look later. |
Released as version 3.15-RC1, you can try that and hopefully that addresses most of the points above. |
Oh what I mean is Now I can see I think I'm fine with this but we should update the In my ancient internal config library that we use in my company we have an enum of TLDR I like the changes just need some javadoc updates. |
An alternative would be to add a This might be preferrable in that:
If we make that change, is Sticking with the single Hmmm. Edit: the opposite style is to add a |
Hi @SentryMan , when you are back if you could just check if you are good with leaving this as a single If you are good with that and we don't want to change to add a |
I'm good with it, but I'd let it sit in RC a little more in case we cook up more ideas. |
Yeah cool. This RC has bug fixes in it though so I don't want to sit on it too long. |
@rbygrave Sorry for the delay on the response. The only reason why I can see making So I don't know if that requires bumping a major for you... these days I have no idea what version policy folks are doing (I'm not sure if you saw my reddit post about semver). I looked at our in house configuration library (one day I will just open source it so you and @SentryMan can laugh at the over engineering) and it appears we rarely do The only time However our config lib has a similar mechanism to Honestly it added a whole bunch of complexity such that we created an enum called Just to give an idea of the disturbing level complexity you can get with LoadFlags: public enum LoadFlag {
NOT_REQUIRED,
NOT_EMPTY,
NO_OVERRIDE,
FORCE,
NO_REPLACE_EXISTING_KEY_VALUE,
NO_ADD_KEY_VALUES,
STOP_ON_FIRST_FOUND,
NO_LOAD_CHILDREN,
NO_RESOURCE_PROVIDERS,
NO_DISCOVER_SERVICE_PROVIDERS,
NO_FINAL_INTERPOLATION,
NO_INTERPOLATION,
NO_LOGGING,
NO_RELOAD;
...
} |
So I'm good with The only thing I think that would seal the deal for me is to make The reason is if one wants to figure out if a darn resource has loaded or not (see above we have |
That is excellent insight / feedback - thanks!!
Yes, re-enforces the idea that we should try to keep it as simple as we can etc.
Great.
Lets add some logging there - I agree that is a real PITA when that is missing and people just want to know what was loaded.
I'm happy to bump the major for this. For me, I think this boils down to this change in behaviour of |
If we're bumping a major might as well add that service loader change |
…#141 Follow up for #147 #141 to add appropriate logging for resources loaded and also when not found and not loaded. Also adds some requireNonNull on builder parameters being set Note that the InitialLoader (default configuration loading) already logs the sources that were loaded so just tidy only changes in InitialLoader
What JDK version is avaje config compiled? If 17 @SentryMan parent the class that is to be registered as the one and only SPI a sealed class like I did here: https://jstach.io/rainbowgum/io.jstach.rainbowgum/io/jstach/rainbowgum/spi/RainbowGumServiceProvider.html EDIT I see JDK 11 as the min so I guess no sealed class. |
@SentryMan sorry for the sporadic comments (its post work and on and off). But I forgot to add the |
Improve Builder logging for loading resources and files - followup for #141
We have got the ServiceLoader change in now so that completes all the tasks mentioned here. So now I think it's just a matter of confirming we are all good with |
@rob-bygrave I will put the change in version (RC) on rainbowgum to try it out today. Thanks! |
How we looking? |
Just to say 4.0 is actually released. I assumed we were all good and released it (quite a few days ago now). |
InitialLoader
/InitialLoaderContext
does several things different than what theConfiguration.builder
does that are very hard to replicate with the builder.For example let us say I want to replicate most of the default initialization:
One them is this:
There are several problems with the above. I can't specify a
maybeLoad
and or fallbacks. I also had the surprise that the defaultresourceLoader
does not do:ClassLoader.getSystemResourceAsStream
which is done inio.avaje.config.InitialLoadContext
:It seems there is a lot of duplication between the builder and InitialLoadContext.
The above I would expect:
And the default resourceLoader to handle the
ClassLoader.getSystemResourceAsStream(resourcePath)
fallback.The text was updated successfully, but these errors were encountered: