У меня создалось впечатление, что Foo::new
- это просто синтаксический сахар для () → new Foo()
и они должны вести себя одинаково. Однако, похоже, это не так. Здесь фон:
С Java-8 я использую стороннюю библиотеку с Optional<Foo> foo
и этой оскорбительной строкой:
foo.orElseGet(JCacheTimeZoneCache::new);
JCacheTimeZoneCache
использует в своем конструкторе что-то из дополнительной библиотеки JCache, которой у меня нет в моем классе. С отладчиком я проверил, что foo не является нулевым, поэтому он фактически не должен создавать экземпляр JCacheTimeZoneCache, и поэтому недостающая библиотека JCache не должна быть проблемой. Однако он взрывается с помощью stacktrace, жалующегося на недостающую библиотеку JCache:
Caused by: java.lang.BootstrapMethodError: java.lang.IllegalAccessError: no such constructor: net.fortuna.ical4j.util.JCacheTimeZoneCache.<init>()void/newInvokeSpecial
at net.fortuna.ical4j.model.TimeZoneLoader.cacheInit(TimeZoneLoader.java:275) ~[ical4j-3.0.0.jar:na]
at net.fortuna.ical4j.model.TimeZoneLoader.<init>(TimeZoneLoader.java:81) ~[ical4j-3.0.0.jar:na]
at net.fortuna.ical4j.model.TimeZoneRegistryImpl.<init>(TimeZoneRegistryImpl.java:125) ~[ical4j-3.0.0.jar:na]
at net.fortuna.ical4j.model.TimeZoneRegistryImpl.<init>(TimeZoneRegistryImpl.java:116) ~[ical4j-3.0.0.jar:na]
at net.fortuna.ical4j.model.DefaultTimeZoneRegistryFactory.createRegistry(DefaultTimeZoneRegistryFactory.java:48) ~[ical4j-3.0.0.jar:na]
at net.fortuna.ical4j.data.CalendarBuilder.<init>(CalendarBuilder.java:105) ~[ical4j-3.0.0.jar:na]
at de.malkusch.trashcollection.infrastructure.schedule.ical.VEventRepository.downloadVEvents(VEventRepository.java:46) ~[classes/:na]
at de.malkusch.trashcollection.infrastructure.schedule.ical.VEventRepository.<init>(VEventRepository.java:35) ~[classes/:na]
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) ~[na:1.8.0_172]
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62) ~[na:1.8.0_172]
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45) ~[na:1.8.0_172]
at java.lang.reflect.Constructor.newInstance(Constructor.java:423) ~[na:1.8.0_172]
at org.springframework.beans.BeanUtils.instantiateClass(BeanUtils.java:170) ~[spring-beans-5.0.7.RELEASE.jar:5.0.7.RELEASE]
... 80 common frames omitted
Caused by: java.lang.IllegalAccessError: no such constructor: net.fortuna.ical4j.util.JCacheTimeZoneCache.<init>()void/newInvokeSpecial
at java.lang.invoke.MethodHandleNatives.linkMethodHandleConstant(MethodHandleNatives.java:483) ~[na:1.8.0_172]
... 93 common frames omitted
Caused by: java.lang.NoClassDefFoundError: javax/cache/configuration/Configuration
at java.lang.invoke.MethodHandleNatives.resolve(Native Method) ~[na:1.8.0_172]
at java.lang.invoke.MemberName$Factory.resolve(MemberName.java:975) ~[na:1.8.0_172]
at java.lang.invoke.MemberName$Factory.resolveOrFail(MemberName.java:1000) ~[na:1.8.0_172]
at java.lang.invoke.MethodHandles$Lookup.resolveOrFail(MethodHandles.java:1394) ~[na:1.8.0_172]
at java.lang.invoke.MethodHandles$Lookup.linkMethodHandleConstant(MethodHandles.java:1750) ~[na:1.8.0_172]
at java.lang.invoke.MethodHandleNatives.linkMethodHandleConstant(MethodHandleNatives.java:477) ~[na:1.8.0_172]
... 93 common frames omitted
Caused by: java.lang.ClassNotFoundException: javax.cache.configuration.Configuration
at java.net.URLClassLoader.findClass(URLClassLoader.java:381) ~[na:1.8.0_172]
at java.lang.ClassLoader.loadClass(ClassLoader.java:424) ~[na:1.8.0_172]
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:349) ~[na:1.8.0_172]
at java.lang.ClassLoader.loadClass(ClassLoader.java:357) ~[na:1.8.0_172]
... 99 common frames omitted
Сначала я удивлен этой ошибкой, поскольку код не создает экземпляр JCacheTimeZoneCache. Хорошо, добавив JCache в путь класса, это исправит. Но автор библиотеки сделал совсем другое решение:
foo.orElseGet(() -> new JCacheTimeZoneCache());
Теперь я полностью удивлен? У меня на самом деле два вопроса:
- Почему JCacheTimeZoneCache :: new вызывает это исключение в первую очередь, когда конструктор никогда не вызывался?
- Почему
() → new JCacheTimeZoneCache()
исправить эту проблему?