unitsofmeasurement / uom-systems

Units of Measurement Systems
http://www.uom.systems
Other
36 stars 17 forks source link

AbstractError when migrating to ServiceProvider.getFormatService() instead of getUnitFormatService() #142

Closed keilw closed 5 years ago

keilw commented 5 years ago

@lfoppiano commented on Tue Jun 11 2019

I've updated to indyria 2.0-PRD, and I've noticed that getUnitFormatService() was deprecated, in favour of getFormatService().

However when doing that I get NullPointerException() coming from within getformatService().

Here my code, where a load all possible service providers to use them later for parsing:

for (ServiceProvider provider : ServiceProvider.available()) {
            UnitFormatService formatService = provider.getFormatService();

            final String providerName = provider.getClass().getName();
            unitFormats.put(providerName, formatService.getUnitFormat());
        }

I get java.lang.AbstractMethodError: javax.measure.spi.ServiceProvider.getFormatService()Ljavax/measure/spi/FormatService;

My dependencies are:

    compile 'tech.units:indriya:2.0-EDR'
    compile group: 'si.uom', name: 'si-units-java8', version: '1.2'
    compile group: 'si.uom', name: 'si-quantity', version: '1.2'

we've discussed already in the past but I could not find the issue.

Thank you in advance.


@keilw commented on Tue Jun 11 2019

You cannot use si-units-java8 (which is in fact based on a completely different implementation, uom-se !) or si-quantity in version 1.2 with Indriya 2.0. If you want to use uom-se, you can find it here, but it won't implement JSR 385. The correct combination for Indriya 2 would be the 2.0-SNAPSHOT releases of these libraries, otherwise please use Indriya 1.x, currently 1.3 as seen in the dependencies of si-units. If you want to use Indriya, please make sure it's si-units without the "java8", that is a legacy version we no longer maintain after 2.0. Sorry for the confusion, but compared to a whole new major version of the JDK every 6 months I guess that still isn't so bad ;-)


@lfoppiano commented on Thu Jun 13 2019

Thank you @keilw !

So now I have

    compile 'tech.units:indriya:2.0-PRD'
    compile group: 'si.uom', name: 'si-units', version: '2.0-SNAPSHOT'
    compile group: 'si.uom', name: 'si-quantity', version: '2.0-SNAPSHOT'

Should I also add all the systems libraries (version 2.0-SNAPSHOT), like:

//    compile group: 'systems.uom', name: 'systems-quantity', version: '1.0'
//    compile group: 'systems.uom', name: 'systems-ucum-java8', version: '1.0'
//    compile group: 'systems.uom', name: 'systems-unicode-java8', version: '1.0'
//    compile group: 'systems.uom', name: 'systems-common', version: '1.0'
//    compile group: 'systems.uom', name: 'systems-unicode', version: '1.0'
//    compile group: 'systems.uom', name: 'systems-ucum', version: '1.0'

Also, the -java8 libraries should be ignored as well in this case?


@lfoppiano commented on Thu Jun 13 2019

Again me, so if I use these versions:

    compile 'tech.units:indriya:2.0-PRD'
    compile group: 'si.uom', name: 'si-units', version: '2.0-SNAPSHOT'
    compile group: 'si.uom', name: 'si-quantity', version: '2.0-SNAPSHOT'

I need to build si-units 2.0-SNAPSHOT, when I try to do so, I get a problem with a test:

[ERROR] /Users/lfoppiano/development/projects/uom/si-units/units/src/test/java/si/uom/PrefixTest.java:[87,47] no suitable method found for of(double,double)
    method tech.units.indriya.function.RationalConverter.of(java.math.BigInteger,java.math.BigInteger) is not applicable
      (argument mismatch; double cannot be converted to java.math.BigInteger)
    method tech.units.indriya.function.RationalConverter.of(long,long) is not applicable
      (argument mismatch; possible lossy conversion from double to long)

The problem is that this version 2.0-SNAPSHOT is using indyra 2.0-SNAPSHOT... so should I use directly that version?

I'm not sure I've understood which versions to use with indyra 2.0-PRD..

Thank you


@keilw commented on Thu Jun 13 2019

I'm afraid, you need to use indriya 2.0-SNAPSHOT. @andi-huber and a few others hav done a bit of improvement under the hood, so especially the whole RationalConverter changed in the last weeks. It it advisable to use the Snapshot builds here until all go Final (https://jcp.org/en/jsr/detail?id=385 shows, the Public Review Final Approval Ballot is still pending)


@andi-huber commented on Thu Jun 13 2019

You might be interested in having a look at jitpack [1]. It eg. allows to build against the latest commit of the master branch.

[1] https://jitpack.io/#unitsofmeasurement/indriya


@keilw commented on Thu Jun 13 2019

That's good to know, thanks. Every snapshot build also gets deployed to JFrog/Bintray.


@lfoppiano commented on Fri Jun 14 2019

@keilw do I need any special configuration for getting the snapshots from Bintray? Here I don't see any snapshots: https://bintray.com/unitsofmeasurement/maven

@andi-huber on jitpack are there also other libraries from unitsofmeasurement? Cause, for example the version 2.0-SNAPSHOT of si-units doesn't seems to be there: https://jitpack.io/#unitsofmeasurement/si-units am I looking in the wrong place?

UPDATE: I'm trying to include also si-units from jitpack but it doesn't seems to be building... https://jitpack.io/com/github/unitsofmeasurement/si-units/master/build.log


@lfoppiano commented on Fri Jun 14 2019

I've built in local version 2.0-SNAPSHOT of indriya, si-unit and si-quantities (I had to disable tests on the former - see related ticket in si-units). What else do I need?

I cannot build uom-systems... see related ticket...


@lfoppiano commented on Fri Jun 14 2019

Me again... So after trial and error on several combination I finally reach a sort of stable combination of libraries.. although I would like to use the version 2.0-SNAPSHOT (once i manage to build it).

Here my dependencies:

    compile 'tech.units:indriya:1.3'
    compile group: 'si.uom', name: 'si-units', version: '1.2'
    compile group: 'si.uom', name: 'si-quantity', version: '1.2'
    compile group: 'systems.uom', name: 'systems-quantity', version: '1.0'
    compile group: 'systems.uom', name: 'systems-common', version: '1.0'
    compile group: 'systems.uom', name: 'systems-unicode', version: '1.0'
    compile group: 'systems.uom', name: 'systems-ucum', version: '1.0'

I don't use system-xy-java8, is it correct to do so?

Anyway at initialisation I have this error:

Jun 14, 2019 1:58:50 PM tech.units.indriya.format.SymbolMap <init>
SEVERE: Error
java.lang.ClassNotFoundException: tec.units.indriya.unit.Units
    at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:583)
    at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:178)
    at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:521)
    at java.base/java.lang.Class.forName0(Native Method)
    at java.base/java.lang.Class.forName(Class.java:315)
    at tech.units.indriya.format.SymbolMap.<init>(SymbolMap.java:116)
    at tech.units.indriya.format.SymbolMap.of(SymbolMap.java:143)
    at systems.uom.ucum.format.UCUMFormat$Print.<clinit>(UCUMFormat.java:360)
    at systems.uom.ucum.format.UCUMFormat.getInstance(UCUMFormat.java:105)
    at systems.uom.ucum.internal.UCUMFormatService.<init>(UCUMFormatService.java:59)
    at systems.uom.ucum.internal.UCUMServiceProvider.getUnitFormatService(UCUMServiceProvider.java:57)
    at org.grobid.core.data.normalization.QuantityNormalizer.<init>(QuantityNormalizer.java:52)
    at org.grobid.core.engines.QuantityParser.<init>(QuantityParser.java:48)
    at org.grobid.core.engines.QuantityParser.getNewInstance(QuantityParser.java:67)
    at org.grobid.core.engines.QuantityParser.getInstance(QuantityParser.java:54)
    at org.grobid.core.engines.QuantityParserIntegrationTests.setUp(QuantityParserIntegrationTests.java:38)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.base/java.lang.reflect.Method.invoke(Method.java:566)
    at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
    at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
    at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
    at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:24)
    at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57)
    at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
    at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
    at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
    at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
    at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
    at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26)
    at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
    at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
    at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:68)
    at com.intellij.rt.execution.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:47)
    at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:242)
    at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:70)

which is thrown at this point:

 UnitFormatService formatService = provider.getUnitFormatService();

If you see the complete code in my first comment, however now, if I use getFormatService(), I will get this error:

Caused by: java.lang.AbstractMethodError: Receiver class systems.uom.common.internal.CommonServiceProvider does not define or inherit an implementation of the resolved method abstract getFormatService()Ljavax/measure/spi/FormatService; of abstract class javax.measure.spi.ServiceProvider.

Any advice?

Thank you in advance


@keilw commented on Fri Jun 14 2019

You cannot use getFormatService if you go back to the 1.x versions. That is clear, the other problem is some earlier version of Indriya accidentially referenced. I suppose in one of the other Systems, because SI Units has undergone more work when the Metric System was redefined. Could you try the 1.1-SNAPSHOT of uom-systems? If that still shows the problem we'll redeploy that. Thank you for your patience and help.


@lfoppiano commented on Fri Jun 14 2019

@keilw thanks for your help. I'm checking right away. Should I also include the -java8 libraries of uom-systems?


@lfoppiano commented on Fri Jun 14 2019

@keilw where should I get the 1.1-SNAPSHOT? as I mentioned https://github.com/unitsofmeasurement/indriya/issues/231#issuecomment-501908538 I'm not finding any snapshot in bintray actually.


@lfoppiano commented on Mon Jun 17 2019

Another test I've done, I've managed to build everything 2.0-SNAPSHOT (with si-units and si-quantity, from @andi-huber). I have tried uom-system 1.1-SNAPSHOT but it was not found, so I use the 2.0-SNAPSHOT:

    compile 'tech.units:indriya:2.0-SNAPSHOT'
    compile group: 'si.uom', name: 'si-units', version: '2.0-SNAPSHOT'
    compile group: 'si.uom', name: 'si-quantity', version: '2.0-SNAPSHOT'
    compile group: 'systems.uom', name: 'systems-quantity', version: '2.0-SNAPSHOT'
    compile group: 'systems.uom', name: 'systems-common', version: '2.0-SNAPSHOT'
    compile group: 'systems.uom', name: 'systems-unicode', version: '2.0-SNAPSHOT'
    compile group: 'systems.uom', name: 'systems-ucum', version: '2.0-SNAPSHOT'

the result is still failing on ServiceProvider.available() call:

Caused by: java.lang.NoClassDefFoundError: tech/units/indriya/spi/DefaultServiceProvider
    at java.lang.ClassLoader.defineClass1(Native Method)
    at java.lang.ClassLoader.defineClass(ClassLoader.java:763)
    at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:142)
    at java.net.URLClassLoader.defineClass(URLClassLoader.java:468)
    at java.net.URLClassLoader.access$100(URLClassLoader.java:74)
    at java.net.URLClassLoader$1.run(URLClassLoader.java:369)
    at java.net.URLClassLoader$1.run(URLClassLoader.java:363)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.net.URLClassLoader.findClass(URLClassLoader.java:362)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
    at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:349)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
    at java.lang.Class.forName0(Native Method)
    at java.lang.Class.forName(Class.java:348)
    at java.util.ServiceLoader$LazyIterator.nextService(ServiceLoader.java:370)
    at java.util.ServiceLoader$LazyIterator.next(ServiceLoader.java:404)
    at java.util.ServiceLoader$1.next(ServiceLoader.java:480)
    at java.util.Iterator.forEachRemaining(Iterator.java:116)
    at java.util.Spliterators$IteratorSpliterator.forEachRemaining(Spliterators.java:1801)
    at java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:481)
    at java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:471)
    at java.util.stream.ReduceOps$ReduceOp.evaluateSequential(ReduceOps.java:708)
    at java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234)
    at java.util.stream.ReferencePipeline.collect(ReferencePipeline.java:499)
    at javax.measure.spi.ServiceProvider.available(ServiceProvider.java:266)
    [...]
Caused by: java.lang.ClassNotFoundException: tech.units.indriya.spi.DefaultServiceProvider
    at java.net.URLClassLoader.findClass(URLClassLoader.java:382)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
    at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:349)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
    ... 57 more

What about the https://github.com/unitsofmeasurement/indriya/issues/231#issuecomment-502000234?

lfoppiano commented 5 years ago

after successfully built all the libraries at version 2.0-SNAPSHOT (https://github.com/unitsofmeasurement/si-units/issues/67#issuecomment-503354458) I've got again the ClassNotFoundException. Not sure how should address the problem

keilw commented 5 years ago

Please wait for the latest snapshot of these artifacts. A lot has changed, not only did https://github.com/unitsofmeasurement/indriya/issues/237 so JUnit tests e.g. in si-units needed updating. I hope that uom-systems here is ready tonight or tomorrow (which is also a holiday) then I'll push it and close this ticket.

lfoppiano commented 5 years ago

@keilw no worries, it can wait a couple more days. I'm currently using the stable version.

keilw commented 5 years ago

@lfoppiano This should be addressed in the 2.0-SNAPSHOT of all relevant artifacts now. Could you please check if it works for you now?

lfoppiano commented 5 years ago

@keilw thanks!

I tried to see if the artifacts were somewhere, but they were not found using https://dl.bintray.com/unitsofmeasurement/maven. Is there a way that I can get the snapshots from bintray?

So I've dropped my .m2/repository and I've built:

but then when I try to build uom-systems I got a test failing:

[ERROR] Tests run: 7, Failures: 1, Errors: 0, Skipped: 0, Time elapsed: 0.006 s <<< FAILURE! - in systems.uom.ucum.format.UnitFormatPrefixTest
[ERROR] testKibiLiter(systems.uom.ucum.format.UnitFormatPrefixTest)  Time elapsed: 0.005 s  <<< FAILURE!
org.junit.ComparisonFailure: expected:<[L.1024]> but was:<[KiL]>
    at org.junit.Assert.assertEquals(Assert.java:115)
    at org.junit.Assert.assertEquals(Assert.java:144)
    at systems.uom.ucum.format.UnitFormatPrefixTest.testKibiLiter(UnitFormatPrefixTest.java:83)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.base/java.lang.reflect.Method.invoke(Method.java:566)
    at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
    at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
    at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
    at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
    at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57)
    at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
    at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
    at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
    at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
    at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
    at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
    at org.apache.maven.surefire.junit4.JUnit4Provider.execute(JUnit4Provider.java:365)
    at org.apache.maven.surefire.junit4.JUnit4Provider.executeWithRerun(JUnit4Provider.java:273)
    at org.apache.maven.surefire.junit4.JUnit4Provider.executeTestSet(JUnit4Provider.java:238)
    at org.apache.maven.surefire.junit4.JUnit4Provider.invoke(JUnit4Provider.java:159)
    at org.apache.maven.surefire.booter.ForkedBooter.invokeProviderInSameClassLoader(ForkedBooter.java:379)
    at org.apache.maven.surefire.booter.ForkedBooter.runSuitesInProcess(ForkedBooter.java:340)
    at org.apache.maven.surefire.booter.ForkedBooter.execute(ForkedBooter.java:125)
    at org.apache.maven.surefire.booter.ForkedBooter.main(ForkedBooter.java:413)
keilw commented 5 years ago

Yes you can, take a look at repositories in the bottom of e.g. https://github.com/unitsofmeasurement/uom-demos/blob/master/pom.xml on how to use both Bintray repositories. Here https://circleci.com/gh/unitsofmeasurement/uom-systems all tests passed, so unless a dependency has since been refreshed, it should work if you take everything as Snapshot.

lfoppiano commented 5 years ago

OK I will check.

BTW I still haven't understood. Should I also include the -java8 packages, within uom-system (https://github.com/unitsofmeasurement/indriya/issues/231#issuecomment-502000234)?

keilw commented 5 years ago

No more -java8 if you're using 2.0-SNAPSHOT.

lfoppiano commented 5 years ago

@keilw Thanks!

I was using the wrong repository.

The build works, I'm using these dependencies:

    compile 'tech.units:indriya:2.0-SNAPSHOT'
    compile group: 'si.uom', name: 'si-units', version: '2.0-SNAPSHOT'
    compile group: 'si.uom', name: 'si-quantity', version: '2.0-SNAPSHOT'
    compile group: 'systems.uom', name: 'systems-quantity', version: '2.0-SNAPSHOT'
    compile group: 'systems.uom', name: 'systems-common', version: '2.0-SNAPSHOT'
    compile group: 'systems.uom', name: 'systems-unicode', version: '2.0-SNAPSHOT'
    compile group: 'systems.uom', name: 'systems-ucum', version: '2.0-SNAPSHOT'

Now, my usual code has been updated to

for (ServiceProvider provider : ServiceProvider.available()) {
         UnitFormatService formatService = provider.getFormatService();

         final String providerName = provider.getClass().getName();
         unitFormats.put(providerName, formatService.getUnitFormat());
}

But I get

java.util.ServiceConfigurationError: javax.measure.spi.FormatService: Provider tech.units.indriya.internal.format.DefaultFormatService could not be instantiated

    at java.util.ServiceLoader.fail(ServiceLoader.java:232)
    at java.util.ServiceLoader.access$100(ServiceLoader.java:185)
    at java.util.ServiceLoader$LazyIterator.nextService(ServiceLoader.java:384)
    at java.util.ServiceLoader$LazyIterator.next(ServiceLoader.java:404)
    at java.util.ServiceLoader$1.next(ServiceLoader.java:480)
    at tech.units.indriya.internal.DefaultServiceProvider.loadServices(DefaultServiceProvider.java:134)
    at tech.units.indriya.internal.DefaultServiceProvider.getServices(DefaultServiceProvider.java:99)
    at tech.units.indriya.internal.DefaultServiceProvider.getService(DefaultServiceProvider.java:103)
    at tech.units.indriya.internal.DefaultServiceProvider.getFormatService(DefaultServiceProvider.java:165)
    at org.grobid.core.data.normalization.QuantityNormaliser.<init>(QuantityNormaliser.java:54)
    at org.grobid.core.engines.QuantityParser.<init>(QuantityParser.java:48)
    at org.grobid.core.engines.QuantityParser.getNewInstance(QuantityParser.java:67)
    at org.grobid.core.engines.QuantityParser.getInstance(QuantityParser.java:54)
    at org.grobid.core.engines.QuantityParserIntegrationTests.setUp(QuantityParserIntegrationTests.java:38)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
    at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
    at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
    at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:24)
    at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57)
    at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
    at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
    at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
    at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
    at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
    at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26)
    at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
    at org.junit.runners.Suite.runChild(Suite.java:128)
    at org.junit.runners.Suite.runChild(Suite.java:27)
    at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
    at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
    at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
    at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
    at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
    at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
    at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
    at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:68)
    at com.intellij.rt.execution.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:47)
    at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:242)
    at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:70)
Caused by: java.lang.NoClassDefFoundError: Could not initialize class tech.units.indriya.internal.format.DefaultFormatService
    at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
    at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
    at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
    at java.lang.reflect.Constructor.newInstance(Constructor.java:423)
    at java.lang.Class.newInstance(Class.java:442)
    at java.util.ServiceLoader$LazyIterator.nextService(ServiceLoader.java:380)
    ... 42 more

This happens with all the ServiceProviders returned by ServiceProvider.available(). Here what I have:

result = {ArrayList@2226}  size = 5
 0 = {UCUMServiceProvider@2228} "UCUMServiceProvider"
 1 = {DefaultServiceProvider@2229} "Default"
 2 = {SIServiceProvider@2230} "SI"
 3 = {UnicodeServiceProvider@2231} "Unicode"
 4 = {CommonServiceProvider@2232} "Common"

Something missing?

keilw commented 5 years ago

ServiceProvider.available() works like that now. After @desruisseaux made changes in version 2, There is a question https://github.com/unitsofmeasurement/unit-api/issues/195 about the priority, but it only affects the order of the ServiceProviders you also mentioned. UCUM is the only module so far that puts itself to be current() otherwise there is no strong need, especially since we added ServiceProvider.of() to call the desired provider by name as well. Would you have a JUnit test to replicate your problem? It sounds like you still have old (1.x) and new (2.x) modules interfering with each other, that would explain why DefaultFormatService can't be found.

lfoppiano commented 5 years ago

It seems that gradle is getting unit-api: 2.0-PRD instead of the SNAPSHOT..

+--- tech.units:indriya:2.0-SNAPSHOT
|    +--- javax.measure:unit-api:2.0-SNAPSHOT -> 2.0-PRD
|    +--- tech.uom.lib:uom-lib-common:2.0-SNAPSHOT
|    |    \--- javax.measure:unit-api:2.0-PRD
|    \--- javax.inject:javax.inject:1
+--- javax.measure:unit-api:2.0-SNAPSHOT -> 2.0-PRD

the 2.0-PRD has a different version of Prefix.java which is the cause of the failure:

java.util.ServiceConfigurationError: javax.measure.spi.FormatService: Provider tech.units.indriya.internal.format.DefaultFormatService could not be instantiated

    at java.util.ServiceLoader.fail(ServiceLoader.java:232)
    at java.util.ServiceLoader.access$100(ServiceLoader.java:185)
    at java.util.ServiceLoader$LazyIterator.nextService(ServiceLoader.java:384)
    at java.util.ServiceLoader$LazyIterator.next(ServiceLoader.java:404)
    at java.util.ServiceLoader$1.next(ServiceLoader.java:480)
    at tech.units.indriya.internal.DefaultServiceProvider.loadServices(DefaultServiceProvider.java:134)
    at tech.units.indriya.internal.DefaultServiceProvider.getServices(DefaultServiceProvider.java:99)
    at tech.units.indriya.internal.DefaultServiceProvider.getService(DefaultServiceProvider.java:103)
    at tech.units.indriya.internal.DefaultServiceProvider.getFormatService(DefaultServiceProvider.java:165)
    at org.grobid.core.data.normalization.UnitNormaliserTest.testInitialisationServiceProvider(UnitNormaliserTest.java:39)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
    at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
    at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
    at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
    at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57)
    at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
    at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
    at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
    at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
    at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
    at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
    at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
    at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:68)
    at com.intellij.rt.execution.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:47)
    at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:242)
    at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:70)
Caused by: java.lang.NoSuchMethodError: javax.measure.Prefix.getValue()Ljava/lang/Number;
    at tech.units.indriya.function.PowerOfIntConverter.of(PowerOfIntConverter.java:66)
    at tech.units.indriya.function.MultiplyConverter.ofPrefix(MultiplyConverter.java:173)
    at tech.units.indriya.format.SymbolMap.label(SymbolMap.java:185)
    at tech.units.indriya.format.SymbolMap.<init>(SymbolMap.java:126)
    at tech.units.indriya.format.SymbolMap.of(SymbolMap.java:143)
    at tech.units.indriya.format.EBNFUnitFormat.<init>(EBNFUnitFormat.java:200)
    at tech.units.indriya.format.EBNFUnitFormat.<clinit>(EBNFUnitFormat.java:170)
    at tech.units.indriya.internal.format.DefaultFormatService.<clinit>(DefaultFormatService.java:64)
    at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
    at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
    at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
    at java.lang.reflect.Constructor.newInstance(Constructor.java:423)
    at java.lang.Class.newInstance(Class.java:442)
    at java.util.ServiceLoader$LazyIterator.nextService(ServiceLoader.java:380)
    ... 29 more

I've digged and noticed that uom-lib somehow has 2.0-PRD versions that are overriding the 2.0-SNAPSHOTS versions...

if I force gradle to use unit-api 2.0-SNAPSHOT, that solves the problem

configurations.all {
    resolutionStrategy {
        force 'javax.measure:unit-api:2.0-SNAPSHOT'
    }
}

On the other hand, using maven the problem doesn't occurs... the same unit test (the code in first comment) within the indriya project, works fine...

keilw commented 5 years ago

I noticed Gradle isn't always that good with repository resolution, but glad, you found a solution there as well. Can we close the ticket?

lfoppiano commented 5 years ago

@keilw I was wondering why there is the reference to the 2.0-PRD in the parent actually... In theory the 2.0-PRD is not compatible with the current SNAPSHOT, isn't it?

If this is not a problem, yes, you can close the ticket 🙂

lfoppiano commented 5 years ago

I have more questions related to the FormatServices, somehow related to the code mentioned at the beginning.

Currently this is the result of the process to collect the various UnitFormatService. Looks like all the various providers shares the same implementation of SimpleUnitFormat. Is it normal or I'm doing something wrong?

unitFormats = {HashMap@3934}  size = 5
 "Unicode" -> {SimpleUnitFormat$DefaultFormat@4122} "SimpleUnitFormat"
 "SI" -> {SimpleUnitFormat$DefaultFormat@4122} "SimpleUnitFormat"
 "UCUMServiceProvider" -> {SimpleUnitFormat$DefaultFormat@4122} "SimpleUnitFormat"
 "Default" -> {SimpleUnitFormat$DefaultFormat@4122} "SimpleUnitFormat"
 "Common" -> {SimpleUnitFormat$DefaultFormat@4122} "SimpleUnitFormat"

Unfortunately the more I dig, the more questions I got... Let me know if you prefer I create a new issue.

keilw commented 5 years ago

Thanks for pointing that out, in the parent POM as a temporary measure of stability we kept the PRD, it's now also SNAPSHOT. Rather strange, that Gradle and Maven behave differently when it comes to that, I'll close this one now. Feel free to open a new ticket but the short answer is yes, SimpleUnitFormat is always static, that's the idea behind a method like label() which works by allowing e.g. the UCUM system to add new labels to an existing SimpleUnitFormat instance.