MenoData / Time4J

Advanced date, time and interval library for Java with sun/moon-astronomy and calendars like Chinese, Coptic, Ethiopian, French Republican, Hebrew, Hijri, Historic Christian, Indian National, Japanese, Julian, Korean, Minguo, Persian, Thai, Vietnamese
GNU Lesser General Public License v2.1
440 stars 64 forks source link

Time4J in Karaf (OSGI) #744

Closed AndyMurgin closed 5 years ago

AndyMurgin commented 6 years ago

Hello everyone! I'm trying to use Time4J in my OSGI-project for sunrise/sunset times calculation. I faced with such a problem. When I try to perform Optional<Moment> result = PlainDate.nowInSystemTime().get(solarTime.sunrise()); I catched java.lang.IllegalStateException: Leap seconds are not supported by configuration (full stacktrace is below). I've tried to explore the sources, but haven't found the root cause.

Could you tell me, what does this exception mean and how I can fix this, please?

java.lang.IllegalStateException: Leap seconds are not supported by configuration.
    at net.time4j.Moment.<init>(Moment.java:630)
    at net.time4j.Moment.of(Moment.java:746)
    at net.time4j.calendar.astro.SolarTime.fromLocalEvent(SolarTime.java:1227)
    at net.time4j.calendar.astro.StdSolarCalculator$2.event(StdSolarCalculator.java:406)
    at net.time4j.calendar.astro.StdSolarCalculator$2.sunrise(StdSolarCalculator.java:358)
    at net.time4j.calendar.astro.SolarTime.lambda$sunrise$14(SolarTime.java:576)
    at net.time4j.engine.ChronoEntity.get(ChronoEntity.java:156)
    at com.echelon.cms.core.time4j.Solaris.calculateSunrise(Solaris.java:27)
    at com.echelon.cms.core.time4j.Solaris.getSolarTiming(Solaris.java:60)
    at com.echelon.cms.core.scheduler.GeolocationResolverImpl.getRealtimeForGroup(GeolocationResolverImpl.java:96)
    at com.echelon.cms.core.scheduler.GeolocationResolverImpl.resolve(GeolocationResolverImpl.java:37)
    at com.echelon.cms.core.scheduler.SchedulerServiceImpl.schedule(SchedulerServiceImpl.java:75)
    at com.echelon.cms.core.scheduler.SchedulerServiceImpl.schedule(SchedulerServiceImpl.java:107)
    at Proxy8489adbf_812d_4d07_b748_0ce7d5facd25.schedule(Unknown Source)
    at com.echelon.cms.web.rest.GroupRestServiceImpl.assignDevices(GroupRestServiceImpl.java:203)[233:com.echelon.cms.web.echelon-web-rest:2.20.2]
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)[:1.8.0_144]
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)[:1.8.0_144]
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)[:1.8.0_144]
    at java.lang.reflect.Method.invoke(Method.java:498)[:1.8.0_144]
    at org.apache.cxf.service.invoker.AbstractInvoker.performInvocation(AbstractInvoker.java:180)[61:org.apache.cxf.cxf-core:3.1.9]
    at org.apache.cxf.service.invoker.AbstractInvoker.invoke(AbstractInvoker.java:96)[61:org.apache.cxf.cxf-core:3.1.9]
    at org.apache.cxf.jaxrs.JAXRSInvoker.invoke(JAXRSInvoker.java:189)[74:org.apache.cxf.cxf-rt-frontend-jaxrs:3.1.9]
    at org.apache.cxf.jaxrs.JAXRSInvoker.invoke(JAXRSInvoker.java:99)[74:org.apache.cxf.cxf-rt-frontend-jaxrs:3.1.9]
    at org.apache.cxf.interceptor.ServiceInvokerInterceptor$1.run(ServiceInvokerInterceptor.java:59)[61:org.apache.cxf.cxf-core:3.1.9]
    at org.apache.cxf.interceptor.ServiceInvokerInterceptor.handleMessage(ServiceInvokerInterceptor.java:96)[61:org.apache.cxf.cxf-core:3.1.9]
    at org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:308)[61:org.apache.cxf.cxf-core:3.1.9]
    at org.apache.cxf.transport.ChainInitiationObserver.onMessage(ChainInitiationObserver.java:121)[61:org.apache.cxf.cxf-core:3.1.9]
    at org.apache.cxf.transport.http.AbstractHTTPDestination.invoke(AbstractHTTPDestination.java:252)[86:org.apache.cxf.cxf-rt-transports-http:3.1.9]
    at org.apache.cxf.transport.servlet.ServletController.invokeDestination(ServletController.java:234)[86:org.apache.cxf.cxf-rt-transports-http:3.1.9]
    at org.apache.cxf.transport.servlet.ServletController.invoke(ServletController.java:208)[86:org.apache.cxf.cxf-rt-transports-http:3.1.9]
    at org.apache.cxf.transport.servlet.ServletController.invoke(ServletController.java:160)[86:org.apache.cxf.cxf-rt-transports-http:3.1.9]
    at org.apache.cxf.transport.servlet.CXFNonSpringServlet.invoke(CXFNonSpringServlet.java:180)[86:org.apache.cxf.cxf-rt-transports-http:3.1.9]
    at org.apache.cxf.transport.servlet.AbstractHTTPServlet.handleRequest(AbstractHTTPServlet.java:299)[86:org.apache.cxf.cxf-rt-transports-http:3.1.9]
    at org.apache.cxf.transport.servlet.AbstractHTTPServlet.doPut(AbstractHTTPServlet.java:235)[86:org.apache.cxf.cxf-rt-transports-http:3.1.9]
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:710)[21:javax.servlet-api:3.1.0]
    at org.apache.cxf.transport.servlet.AbstractHTTPServlet.service(AbstractHTTPServlet.java:274)[86:org.apache.cxf.cxf-rt-transports-http:3.1.9]
    at org.eclipse.jetty.servlet.ServletHolder.handle(ServletHolder.java:812)[186:org.eclipse.jetty.servlet:9.2.19.v20160908]
    at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1669)[186:org.eclipse.jetty.servlet:9.2.19.v20160908]
    at com.echelon.cms.web.filters.CacheFilter.doFilter(CacheFilter.java:27)[233:com.echelon.cms.web.echelon-web-rest:2.20.2]
    at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1652)[186:org.eclipse.jetty.servlet:9.2.19.v20160908]
    at org.apache.shiro.web.servlet.ProxiedFilterChain.doFilter(ProxiedFilterChain.java:61)[246:org.apache.shiro.web:1.3.2]
    at org.apache.shiro.web.servlet.AdviceFilter.executeChain(AdviceFilter.java:108)[246:org.apache.shiro.web:1.3.2]
    at org.apache.shiro.web.servlet.AdviceFilter.doFilterInternal(AdviceFilter.java:137)[246:org.apache.shiro.web:1.3.2]
    at org.apache.shiro.web.servlet.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:125)[246:org.apache.shiro.web:1.3.2]
    at org.apache.shiro.web.servlet.ProxiedFilterChain.doFilter(ProxiedFilterChain.java:66)[246:org.apache.shiro.web:1.3.2]
    at org.apache.shiro.web.servlet.AbstractShiroFilter.executeChain(AbstractShiroFilter.java:449)[246:org.apache.shiro.web:1.3.2]
    at org.apache.shiro.web.servlet.AbstractShiroFilter$1.call(AbstractShiroFilter.java:365)[246:org.apache.shiro.web:1.3.2]
    at org.apache.shiro.subject.support.SubjectCallable.doCall(SubjectCallable.java:90)[245:org.apache.shiro.core:1.3.2]
    at org.apache.shiro.subject.support.SubjectCallable.call(SubjectCallable.java:83)[245:org.apache.shiro.core:1.3.2]
    at org.apache.shiro.subject.support.DelegatingSubject.execute(DelegatingSubject.java:383)[245:org.apache.shiro.core:1.3.2]
    at org.apache.shiro.web.servlet.AbstractShiroFilter.doFilterInternal(AbstractShiroFilter.java:362)[246:org.apache.shiro.web:1.3.2]
    at org.apache.shiro.web.servlet.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:125)[246:org.apache.shiro.web:1.3.2]
    at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1652)[186:org.eclipse.jetty.servlet:9.2.19.v20160908]
    at org.eclipse.jetty.servlet.ServletHandler.doHandle(ServletHandler.java:585)[186:org.eclipse.jetty.servlet:9.2.19.v20160908]
    at org.ops4j.pax.web.service.jetty.internal.HttpServiceServletHandler.doHandle(HttpServiceServletHandler.java:71)[216:org.ops4j.pax.web.pax-web-jetty:4.3.0]
    at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:143)[185:org.eclipse.jetty.server:9.2.19.v20160908]
    at org.eclipse.jetty.security.SecurityHandler.handle(SecurityHandler.java:577)[184:org.eclipse.jetty.security:9.2.19.v20160908]
    at org.eclipse.jetty.server.session.SessionHandler.doHandle(SessionHandler.java:223)[185:org.eclipse.jetty.server:9.2.19.v20160908]
    at org.eclipse.jetty.server.handler.ContextHandler.doHandle(ContextHandler.java:1127)[185:org.eclipse.jetty.server:9.2.19.v20160908]
    at org.ops4j.pax.web.service.jetty.internal.HttpServiceContext.doHandle(HttpServiceContext.java:287)[216:org.ops4j.pax.web.pax-web-jetty:4.3.0]
    at org.eclipse.jetty.servlet.ServletHandler.doScope(ServletHandler.java:515)[186:org.eclipse.jetty.servlet:9.2.19.v20160908]
    at org.eclipse.jetty.server.session.SessionHandler.doScope(SessionHandler.java:185)[185:org.eclipse.jetty.server:9.2.19.v20160908]
    at org.eclipse.jetty.server.handler.ContextHandler.doScope(ContextHandler.java:1061)[185:org.eclipse.jetty.server:9.2.19.v20160908]
    at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:141)[185:org.eclipse.jetty.server:9.2.19.v20160908]
    at org.ops4j.pax.web.service.jetty.internal.JettyServerHandlerCollection.handle(JettyServerHandlerCollection.java:80)[216:org.ops4j.pax.web.pax-web-jetty:4.3.0]
    at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:97)[185:org.eclipse.jetty.server:9.2.19.v20160908]
    at org.eclipse.jetty.server.Server.handle(Server.java:499)[185:org.eclipse.jetty.server:9.2.19.v20160908]
    at org.eclipse.jetty.server.HttpChannel.handle(HttpChannel.java:311)[185:org.eclipse.jetty.server:9.2.19.v20160908]
    at org.eclipse.jetty.server.HttpConnection.onFillable(HttpConnection.java:257)[185:org.eclipse.jetty.server:9.2.19.v20160908]
    at org.eclipse.jetty.io.AbstractConnection$2.run(AbstractConnection.java:544)[177:org.eclipse.jetty.io:9.2.19.v20160908]
    at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:635)[188:org.eclipse.jetty.util:9.2.19.v20160908]
    at org.eclipse.jetty.util.thread.QueuedThreadPool$3.run(QueuedThreadPool.java:555)[188:org.eclipse.jetty.util:9.2.19.v20160908]
    at java.lang.Thread.run(Thread.java:748)[:1.8.0_144]
MenoData commented 6 years ago

Thanks for feedback. On first glance, the error message is relatively clear for me but arises further questions.

In detail:

The astro-package of Time4J takes into account the different time scales used in astronomical calculations for the sake of ultra correctness. Especially, the scales UT and TT are used and then converted to UTC inside the Moment-constructor. But all these scales will not work without enabled leap second support. The core-module has built-in leap seconds, however. And the tzdata-module (don't know if you use it, too) also has its leap seconds. The error message tells you that Time4J was not able to find the leap seconds inside its own core module (although they really exist including the data!).

How does Time4J search for leap second support?

It does so via a service loader mechanism. My suspicion: Your OSGi-environment does not work well with service loaders given in standard Java. So I even suspect that all internationalization data of Time4J are NOT available, too, in your set-up (Time4J would then fall back to JDK-data which don't have the same quality and content, however).

What to do now?

I am not an OSGi-expert but have found following links which might help you:

http://blog.osgi.org/2013/02/javautilserviceloader-in-osgi.html http://aries.apache.org/modules/spi-fly.html http://enroute.osgi.org/tutorial_wrap/300-serviceloader.html https://github.com/CoastalHacking/example-serviceloader

It seems you have to change/configure your OSGi-setup in some way. The actual service loader mechanism uses following META-INF-file inside the core module:

https://github.com/MenoData/Time4J/blob/master/core/src/main/resources/META-INF/services/net.time4j.scale.LeapSecondProvider

Sure, it would be nice if an OSGI-workaround could be automatically done by Time4J, but as said before, I am not an expert for OSGi. Any help on this area is welcome.

MenoData commented 6 years ago

By the way, I can also imagine to deliver a patch in next version of Time4J such that the default leap second data of core-module will automatically be loaded (as fallback) if the service provider mechanism does not work.

But it would just be a workaround and not tackle the real cause of your problem, namely the failing interaction between your OSGI-setup and the service loader architecture of Time4J.

MenoData commented 6 years ago

Sorry for late pause. Probably next week, I can release a new version of Time4J (v4.35) which will contain an experimental OSGi-manifest so you can test it.

AndyMurgin commented 6 years ago

These are really good news! I will wait for it.

Actually, I tried to make Time4J work in my project (thanks to your references), but the final result was not achieved.

MenoData commented 6 years ago

Now I have released v4.35 which contains some experimental osgi-manifests. For exampe, the core-module has following META-INF-file:

Manifest-Version: 1.0
Bundle-Description: Advanced Date, Time and Interval Library for Java
Bundle-License: http://www.gnu.org/licenses/lgpl-2.1.html
Bundle-SymbolicName: time4j-core
Archiver-Version: Plexus Archiver
Built-By: Meno Hochschild
Bnd-LastModified: 1520446730338
Bundle-ManifestVersion: 2
Import-Package: net.time4j.base,net.time4j.engine,net.time4j.scale,net
 .time4j.tz
Require-Capability: osgi.extender;filter:="(osgi.extender=osgi.service
 loader.registrar)",osgi.ee;filter:="(&(osgi.ee=JavaSE)(version=1.8))"
Tool: Bnd-3.5.0.201709291849
Provide-Capability: osgi.serviceloader;osgi.serviceloader="net.time4j.
 scale.LeapSecondProvider"
Export-Package: net.time4j;uses:="net.time4j.base,net.time4j.engine,ne
 t.time4j.format,net.time4j.scale,net.time4j.tz";version="4.35.0",net.
 time4j.base;version="4.35.0",net.time4j.engine;uses:="net.time4j.base
 ,net.time4j.tz";version="4.35.0",net.time4j.format;uses:="net.time4j.
 engine,net.time4j.scale,net.time4j.tz";version="4.35.0",net.time4j.sc
 ale;uses:="net.time4j.base";version="4.35.0",net.time4j.sql;uses:="ne
 t.time4j";version="4.35.0",net.time4j.tz;uses:="net.time4j.base";vers
 ion="4.35.0"
Bundle-Name: Time4J-Core
Bundle-Version: 4.35.0
Created-By: Apache Maven Bundle Plugin
Build-Jdk: 1.8.0_40

I would be happy to hear your feedback if this works for you. If not then let's look for an alternative.

MenoData commented 6 years ago

Unfortunately, I can still not reproduce your problem by setting up an extra osgi-application using Apache Felix and IntelliJ and Time4J-v4.34. So no chance to test it for me. You are in the better position to test it. Have you been able to test the latest version v4.35?

Anyway, I am thinking now about how to replace the whole service loader mechanism in the next majore version v5.0, see also my issue #525. If so then OSGi should no longer be a problem.

Another point affecting coming version v4.36: I will investigate how to avoid leap second calculations in astronomical calculations if leap seconds are disabled for what ever reason, see issue #761. If that issue is solved then your specific problem described above (calculating the sunrise) should also be solved.

AndyMurgin commented 6 years ago

Unfortunately, after OSGI-manifest is added I can not even start my feature in Karaf :disappointed:

2018-03-23 14:19:29,189 | ERROR | nsole user karaf | ShellUtil | 135 - org.apache.karaf.shell.core - 4.0.8 | Exception caught while executing command org.osgi.service.resolver.ResolutionException: Unable to resolve root: missing requirement [root] osgi.identity; osgi.identity=echelon-devel; type=karaf.feature; version="[2.30.3,2.30.3]"; filter:="(&(osgi.identity=echelon-devel)(type=karaf.feature)(version>=2.30.3)(version<=2.30.3))" [caused by: Unable to resolve echelon-devel/2.30.3: missing requirement [echelon-devel/2.30.3] osgi.identity; osgi.identity=time4j-calendar; type=osgi.bundle; version="[4.35.0,4.35.0]"; resolution:=mandatory [caused by: Unable to resolve time4j-calendar/4.35.0: missing requirement [time4j-calendar/4.35.0] osgi.wiring.package; filter:="(osgi.wiring.package=net.time4j.format.internal)"]]

Actually, I don't know why it occurs now. I just added new version of dependency to parent pom and to the necessary bundle module pom. For version 4.34 there was no such problem.

May be I do something wrong. Sadly. but for now I have not a lot of time to try understand why it doesn't work for me. But I will try later and give you a feedback if the situation will change.

And these are good news about your attempts to avoid service loading or help with my leap seconds issue. Sorry for my late answers, I'll try to track the mentioned issues and think about solutions.

MenoData commented 6 years ago

Good to hear your feedback. The error message seems to indicate that there is a problem with the package net.time4j.format.internal which is a private package inside the core-module but needed in the calendar-module. This is no problem on the class-path but probably in OSGi. Therefore I had meanwhile committed a patch to include such internal packages into the export-statement. This does not mean that users should use such packages (not part of generated javadoc) but at least OSGi should stop to complain.

The other issue of enabling astronomical calculations without leap seconds is already solved (in coming v4.36).

The remaining risk is inside the new OSGi-manifest which contains untested entries like

             <Require-Capability> 
                   osgi.extender; filter:="(osgi.extender=osgi.serviceloader.registrar)" 
             </Require-Capability> 
             <Provide-Capability> 
                  osgi.serviceloader; osgi.serviceloader=net.time4j.tz.ZoneModelProvider 
             </Provide-Capability> 

The rest of the OSGi-manifests does not look critical for me. I will just need to update the tzdata-module to newest tzdata version and then release v4.36 this weekend so you can try it. If you test it then please also try to add the tzdata-module (for example v2.2-2018d, extra to the calendar-module) and read the output of the expression System.out.println(Timezone.getProviderInfo()). This would tell me if the service-loader-mechanism can successfully load the tzdata module or just falls back to the platform tzdata.

MenoData commented 6 years ago

Okay, now I have released v4.36 and think that you should at least be able to start the astronomical calculations in Karaf. And please try to log what the result of Timezone.getProviderInfo() will be.

For the test, don't forget to include also the tzdata-module:

<groupId>net.time4j</groupId>
<artifactId>time4j-tzdata</artifactId>
<version>2.2-2018d</version>

The purpose of this test is to see if the service loader mechanism can be modelled in OSGi-context as specified in the manifest files.

AndyMurgin commented 6 years ago

Hi! Today's morning I have experienced v4.36.
Unfortunately, the problem didn't gone :sob:

I added the following code to my service to test:

SolarTime solarTime = SolarTime.ofLocation(56.3129426, 44.053897);
        Optional<Moment> result = PlainDate.nowInSystemTime().get(solarTime.sunset());
        result.ifPresent(moment -> {
            String string = moment.toZonalTimestamp(() -> "Europe/Moscow").toString();
        });

... and get this:

org.apache.cxf.interceptor.Fault: net.time4j.scale.LeapSecondProvider: Provider net.time4j.scale.spi.DefaultLeapSecondProviderSPI could not be instantiated
    at org.apache.cxf.service.invoker.AbstractInvoker.createFault(AbstractInvoker.java:162)[64:org.apache.cxf.cxf-core:3.1.9]
    at org.apache.cxf.service.invoker.AbstractInvoker.invoke(AbstractInvoker.java:128)[64:org.apache.cxf.cxf-core:3.1.9]
    at org.apache.cxf.jaxrs.JAXRSInvoker.invoke(JAXRSInvoker.java:189)[77:org.apache.cxf.cxf-rt-frontend-jaxrs:3.1.9]
    at org.apache.cxf.jaxrs.JAXRSInvoker.invoke(JAXRSInvoker.java:99)[77:org.apache.cxf.cxf-rt-frontend-jaxrs:3.1.9]
    at org.apache.cxf.interceptor.ServiceInvokerInterceptor$1.run(ServiceInvokerInterceptor.java:59)[64:org.apache.cxf.cxf-core:3.1.9]
    at org.apache.cxf.interceptor.ServiceInvokerInterceptor.handleMessage(ServiceInvokerInterceptor.java:96)[64:org.apache.cxf.cxf-core:3.1.9]
    at org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:308)[64:org.apache.cxf.cxf-core:3.1.9]
    at org.apache.cxf.transport.ChainInitiationObserver.onMessage(ChainInitiationObserver.java:121)[64:org.apache.cxf.cxf-core:3.1.9]
    at org.apache.cxf.transport.http.AbstractHTTPDestination.invoke(AbstractHTTPDestination.java:252)[89:org.apache.cxf.cxf-rt-transports-http:3.1.9]
    at org.apache.cxf.transport.servlet.ServletController.invokeDestination(ServletController.java:234)[89:org.apache.cxf.cxf-rt-transports-http:3.1.9]
    at org.apache.cxf.transport.servlet.ServletController.invoke(ServletController.java:208)[89:org.apache.cxf.cxf-rt-transports-http:3.1.9]
    at org.apache.cxf.transport.servlet.ServletController.invoke(ServletController.java:160)[89:org.apache.cxf.cxf-rt-transports-http:3.1.9]
    at org.apache.cxf.transport.servlet.CXFNonSpringServlet.invoke(CXFNonSpringServlet.java:180)[89:org.apache.cxf.cxf-rt-transports-http:3.1.9]
    at org.apache.cxf.transport.servlet.AbstractHTTPServlet.handleRequest(AbstractHTTPServlet.java:299)[89:org.apache.cxf.cxf-rt-transports-http:3.1.9]
    at org.apache.cxf.transport.servlet.AbstractHTTPServlet.doPost(AbstractHTTPServlet.java:218)[89:org.apache.cxf.cxf-rt-transports-http:3.1.9]
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:707)[22:javax.servlet-api:3.1.0]
    at org.apache.cxf.transport.servlet.AbstractHTTPServlet.service(AbstractHTTPServlet.java:274)[89:org.apache.cxf.cxf-rt-transports-http:3.1.9]
    at org.eclipse.jetty.servlet.ServletHolder.handle(ServletHolder.java:812)[189:org.eclipse.jetty.servlet:9.2.19.v20160908]
    at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1669)[189:org.eclipse.jetty.servlet:9.2.19.v20160908]
    at com.echelon.cms.web.filters.CacheFilter.doFilter(CacheFilter.java:28)[238:com.echelon.cms.web.echelon-web-rest:2.30.3]
    at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1652)[189:org.eclipse.jetty.servlet:9.2.19.v20160908]
    at org.apache.shiro.web.servlet.ProxiedFilterChain.doFilter(ProxiedFilterChain.java:61)[251:org.apache.shiro.web:1.3.2]
    at org.apache.shiro.web.servlet.AdviceFilter.executeChain(AdviceFilter.java:108)[251:org.apache.shiro.web:1.3.2]
    at org.apache.shiro.web.servlet.AdviceFilter.doFilterInternal(AdviceFilter.java:137)[251:org.apache.shiro.web:1.3.2]
    at org.apache.shiro.web.servlet.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:125)[251:org.apache.shiro.web:1.3.2]
    at org.apache.shiro.web.servlet.ProxiedFilterChain.doFilter(ProxiedFilterChain.java:66)[251:org.apache.shiro.web:1.3.2]
    at org.apache.shiro.web.servlet.AbstractShiroFilter.executeChain(AbstractShiroFilter.java:449)[251:org.apache.shiro.web:1.3.2]
    at org.apache.shiro.web.servlet.AbstractShiroFilter$1.call(AbstractShiroFilter.java:365)[251:org.apache.shiro.web:1.3.2]
    at org.apache.shiro.subject.support.SubjectCallable.doCall(SubjectCallable.java:90)[250:org.apache.shiro.core:1.3.2]
    at org.apache.shiro.subject.support.SubjectCallable.call(SubjectCallable.java:83)[250:org.apache.shiro.core:1.3.2]
    at org.apache.shiro.subject.support.DelegatingSubject.execute(DelegatingSubject.java:383)[250:org.apache.shiro.core:1.3.2]
    at org.apache.shiro.web.servlet.AbstractShiroFilter.doFilterInternal(AbstractShiroFilter.java:362)[251:org.apache.shiro.web:1.3.2]
    at org.apache.shiro.web.servlet.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:125)[251:org.apache.shiro.web:1.3.2]
    at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1652)[189:org.eclipse.jetty.servlet:9.2.19.v20160908]
    at org.eclipse.jetty.servlet.ServletHandler.doHandle(ServletHandler.java:585)[189:org.eclipse.jetty.servlet:9.2.19.v20160908]
    at org.ops4j.pax.web.service.jetty.internal.HttpServiceServletHandler.doHandle(HttpServiceServletHandler.java:71)[218:org.ops4j.pax.web.pax-web-jetty:4.3.0]
    at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:143)[188:org.eclipse.jetty.server:9.2.19.v20160908]
    at org.eclipse.jetty.security.SecurityHandler.handle(SecurityHandler.java:577)[187:org.eclipse.jetty.security:9.2.19.v20160908]
    at org.eclipse.jetty.server.session.SessionHandler.doHandle(SessionHandler.java:223)[188:org.eclipse.jetty.server:9.2.19.v20160908]
    at org.eclipse.jetty.server.handler.ContextHandler.doHandle(ContextHandler.java:1127)[188:org.eclipse.jetty.server:9.2.19.v20160908]
    at org.ops4j.pax.web.service.jetty.internal.HttpServiceContext.doHandle(HttpServiceContext.java:287)[218:org.ops4j.pax.web.pax-web-jetty:4.3.0]
    at org.eclipse.jetty.servlet.ServletHandler.doScope(ServletHandler.java:515)[189:org.eclipse.jetty.servlet:9.2.19.v20160908]
    at org.eclipse.jetty.server.session.SessionHandler.doScope(SessionHandler.java:185)[188:org.eclipse.jetty.server:9.2.19.v20160908]
    at org.eclipse.jetty.server.handler.ContextHandler.doScope(ContextHandler.java:1061)[188:org.eclipse.jetty.server:9.2.19.v20160908]
    at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:141)[188:org.eclipse.jetty.server:9.2.19.v20160908]
    at org.ops4j.pax.web.service.jetty.internal.JettyServerHandlerCollection.handle(JettyServerHandlerCollection.java:80)[218:org.ops4j.pax.web.pax-web-jetty:4.3.0]
    at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:97)[188:org.eclipse.jetty.server:9.2.19.v20160908]
    at org.eclipse.jetty.server.Server.handle(Server.java:499)[188:org.eclipse.jetty.server:9.2.19.v20160908]
    at org.eclipse.jetty.server.HttpChannel.handle(HttpChannel.java:311)[188:org.eclipse.jetty.server:9.2.19.v20160908]
    at org.eclipse.jetty.server.HttpConnection.onFillable(HttpConnection.java:257)[188:org.eclipse.jetty.server:9.2.19.v20160908]
    at org.eclipse.jetty.io.AbstractConnection$2.run(AbstractConnection.java:544)[180:org.eclipse.jetty.io:9.2.19.v20160908]
    at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:635)[191:org.eclipse.jetty.util:9.2.19.v20160908]
    at org.eclipse.jetty.util.thread.QueuedThreadPool$3.run(QueuedThreadPool.java:555)[191:org.eclipse.jetty.util:9.2.19.v20160908]
    at java.lang.Thread.run(Thread.java:748)[:1.8.0_144]
Caused by: java.util.ServiceConfigurationError: net.time4j.scale.LeapSecondProvider: Provider net.time4j.scale.spi.DefaultLeapSecondProviderSPI could not be instantiated
    at java.util.ServiceLoader.fail(ServiceLoader.java:232)[:1.8.0_144]
    at java.util.ServiceLoader.access$100(ServiceLoader.java:185)[:1.8.0_144]
    at java.util.ServiceLoader$LazyIterator.nextService(ServiceLoader.java:384)[:1.8.0_144]
    at java.util.ServiceLoader$LazyIterator.next(ServiceLoader.java:404)[:1.8.0_144]
    at java.util.ServiceLoader$1.next(ServiceLoader.java:480)[:1.8.0_144]
    at net.time4j.scale.LeapSeconds.<init>(LeapSeconds.java:201)
    at net.time4j.scale.LeapSeconds.<clinit>(LeapSeconds.java:179)
    at net.time4j.SystemClock.calibrate(SystemClock.java:483)
    at net.time4j.SystemClock.<clinit>(SystemClock.java:95)
    at net.time4j.ZonalClock.<init>(ZonalClock.java:190)
    at net.time4j.ZonalClock.<clinit>(ZonalClock.java:72)
    at net.time4j.PlainDate.nowInSystemTime(PlainDate.java:913)
    at com.echelon.cms.core.model.services.scheduler.solaris.SolarisImpl.getSolarTiming(SolarisImpl.java:56)
    at com.echelon.cms.core.model.services.scheduler.EventUtilsImpl.lambda$null$3(EventUtilsImpl.java:252)
    at java.util.HashMap.computeIfAbsent(HashMap.java:1126)[:1.8.0_144]
    at com.echelon.cms.core.model.services.scheduler.EventUtilsImpl.lambda$solarMemoize$4(EventUtilsImpl.java:252)
    at com.echelon.cms.core.model.services.scheduler.EventUtilsImpl._recurrentCase(EventUtilsImpl.java:218)
    at com.echelon.cms.core.model.services.scheduler.EventUtilsImpl.getNextTrigger(EventUtilsImpl.java:64)
    at com.echelon.cms.core.model.services.scheduler.EventUtilsImpl.getNextTrigger(EventUtilsImpl.java:54)
    at com.echelon.cms.core.model.services.scheduler.EventUtilsImpl.getNextTrigger(EventUtilsImpl.java:49)
    at com.echelon.cms.core.model.validators.EventModelValidator.validateOccurrence(EventModelValidator.java:85)
    at com.echelon.cms.core.model.validators.EventModelValidator.validateCreateWithTokens(EventModelValidator.java:162)
    at com.echelon.cms.core.model.validators.EventModelValidator.validateCreate(EventModelValidator.java:118)
    at com.echelon.cms.core.model.validators.EventModelValidator.validateCreate(EventModelValidator.java:27)
    at com.echelon.cms.core.model.validators.ModelValidatorFacade.lambda$validateCreateWithTokens$4(ModelValidatorFacade.java:78)
    at java.util.stream.ForEachOps$ForEachOp$OfRef.accept(ForEachOps.java:184)[:1.8.0_144]
    at java.util.stream.ReferencePipeline$2$1.accept(ReferencePipeline.java:175)[:1.8.0_144]
    at java.util.ArrayList$ArrayListSpliterator.forEachRemaining(ArrayList.java:1374)[:1.8.0_144]
    at java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:481)[:1.8.0_144]
    at java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:471)[:1.8.0_144]
    at java.util.stream.ForEachOps$ForEachOp.evaluateSequential(ForEachOps.java:151)[:1.8.0_144]
    at java.util.stream.ForEachOps$ForEachOp$OfRef.evaluateSequential(ForEachOps.java:174)[:1.8.0_144]
    at java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234)[:1.8.0_144]
    at java.util.stream.ReferencePipeline.forEach(ReferencePipeline.java:418)[:1.8.0_144]
    at com.echelon.cms.core.model.validators.ModelValidatorFacade.validateCreateWithTokens(ModelValidatorFacade.java:76)
    at com.echelon.cms.core.model.validators.ModelValidatorFacade.validateCreate(ModelValidatorFacade.java:29)
    at Proxy8c0d3764_c94a_434c_a666_b8ac0670a4e3.validateCreate(Unknown Source)
    at com.echelon.cms.core.scheduler.DefaultScheduleServiceImpl.buildAndSave(DefaultScheduleServiceImpl.java:53)
    at Proxy709ecbf0_94f6_49ea_b76f_9bea26cdb868.buildAndSave(Unknown Source)
    at com.echelon.cms.web.rest.CustomerRestServiceImpl.addCustomer(CustomerRestServiceImpl.java:108)[238:com.echelon.cms.web.echelon-web-rest:2.30.3]
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)[:1.8.0_144]
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)[:1.8.0_144]
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)[:1.8.0_144]
    at java.lang.reflect.Method.invoke(Method.java:498)[:1.8.0_144]
    at org.apache.cxf.service.invoker.AbstractInvoker.performInvocation(AbstractInvoker.java:180)[64:org.apache.cxf.cxf-core:3.1.9]
    at org.apache.cxf.service.invoker.AbstractInvoker.invoke(AbstractInvoker.java:96)[64:org.apache.cxf.cxf-core:3.1.9]
    ... 52 more
Caused by: java.lang.IllegalStateException: Stream handler unavailable due to: null
    at org.apache.felix.framework.URLHandlersStreamHandlerProxy.openConnection(URLHandlersStreamHandlerProxy.java:311)
    at java.net.URL.openConnection(URL.java:979)[:1.8.0_144]
    at net.time4j.base.ResourceLoader$StdResourceLoader.load(ResourceLoader.java:334)
    at net.time4j.scale.spi.DefaultLeapSecondProviderSPI.<init>(DefaultLeapSecondProviderSPI.java:68)
    at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)[:1.8.0_144]
    at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)[:1.8.0_144]
    at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)[:1.8.0_144]
    at java.lang.reflect.Constructor.newInstance(Constructor.java:423)[:1.8.0_144]
    at java.lang.Class.newInstance(Class.java:442)[:1.8.0_144]
    at java.util.ServiceLoader$LazyIterator.nextService(ServiceLoader.java:380)[:1.8.0_144]
    ... 95 more

I have no mind why Service loading is not working in my case. The only one - may multi-bundle environment affects it. Sorry for bad news and, nevertheless, thank you for participation!

As you asked, I tried to call Timezone.getProviderInfo(). The result of this is: net.time4j.tz.Timezone:[default-provider=java.util.TimeZone, registered={(name=java.util.TimeZone)}]

What info can I provide to you which can help understand the case better?

MenoData commented 6 years ago

I really appreciate your feedback. Some details (about OSGi) are now clear, some other not yet. I will try to summarize:

At least I get the impression that the manifest entries like

<Require-Capability> 
              osgi.extender; filter:="(osgi.extender=osgi.serviceloader.registrar)" 
</Require-Capability>

have caused your setup to try to activate the service loader.

MenoData commented 6 years ago

Anyway, what can we do now? Three points:

MenoData commented 6 years ago

Okay, now I have released v4.37 which should at least enable you to use the astronomical calculations without crash in OSGi (although the service loader mechanism is still not working in OSGi). You can test it.

My next plan is to prepare a new major version v5.0 which will address the modularization issue even in an OSGi-environment. But it can still take some months due to my limited working capabilities.

MenoData commented 5 years ago

I have now released the new major version v5.0. Use the dependency "time4j-base" in your pom-file. If you also use the tzdata (v5.0-2018f) then don't forget to manually call TZDATA.init() before any other usage of Time4J-code. This special initialization manually registers the tzdata because the service loader mechanism does not work in OSGi.

Thank you very much for your analysis and good luck and happy coding.