google / openrtb-doubleclick

Utilities for DoubleClick Ad Exchange, including OpenRTB mapping, DoubleClick cryptography, metadata and validation
Apache License 2.0
198 stars 82 forks source link

Initialization of AdCategoryMapper #64

Closed marcelomalcher closed 9 years ago

marcelomalcher commented 9 years ago

Hey @opinali,

As I said before, thanks for developing and maintaining this awesome libs.

Well, while working with DoubleClickOpenRtbMapper I faced the following situation after getting an instance of this class.

So, the issue happens due to the number of concurrent calls to DoubleClickOpenRtbMapper (after all, it is RTB, right?). Then, as receiving multiple requests, the JVM fails to execute the static block once, and ends executing more than one time concurrently. As there's only one file, this second (or third, forth...) fails to access the mapping text file (as it is open by another thread) and a ExceptionInInitializerError is thrown. Thus, several subsequent calls to AdCategoryMapper methods end with a NoClassDefFoundError exception.

I solved this by forcing the load of the AdCategoryMapper during the init of my system:

try {
   Class.forName(AdCategoryMapper.class.getName(), true, AdCategoryMapper.class.getClassLoader());
} catch (ClassNotFoundException e) {
   throw new AssertionError(e);
}

This way, when when DoubleClickOpenRtbMapper started to receive requests to convert and used the AdCategoryMapper static methods, it already had the static block executed and had the mapped categories in its static attributes.

I thought about opening a PR with some method like initMappers() in the constructor of DoubleClickOpenRtbMapper to force the loading of mappers like AdCategoryMapper.

What do you think?

opinali commented 9 years ago

I find very strange that concurrent executions of this static block would happen; class initialization shouldn't allow that (unless you have separate classloaders loading the same class...). Do you have stack trace that shows this? And even concurrent loads of the same resource should not cause any problems, they would just create different InputStreams that can read the same thing independently.

marcelomalcher commented 9 years ago

Yes, it is strange. I think that the static block is initialized only once per classload. I am not sure what was happening, perhaps multiple class loaders loading the class in the same time?

I am trying to find the stack trace regarding this problem in in my log files, but it will be a hard task. I know that an exception with the mapper text file was happening and an ExceptionInInitializerError was raised in the first time. Then, all the subsequent calls to the AdCategoryMapper were raising a NoClassDefFoundError.

I will try to find the stack trace and post here. If I do not find I intend to close this issue.

marcelomalcher commented 9 years ago

Closing the issue. I couldn't find the stack trace with the error.