ehn-dcc-development / hcert-kotlin

Kotlin multiplatform implementation of the HCERT/DCC specification
Apache License 2.0
25 stars 25 forks source link

Java Maven Integration #70

Closed Jopasa closed 2 years ago

Jopasa commented 2 years ago

Dear authors & contributors,

I experience problems when including hcert-kotlin into a java spring boot project using maven. As discussed in the readme, I added the dependency to the built maven artifact using:

<dependency>
    <groupId>com.github.ehn-dcc-development</groupId>
    <artifactId>hcert-kotlin</artifactId>
    <version>1.3.2</version>
</dependency>

....
<repository>
    <id>jitpack.io</id>
    <url>https://jitpack.io</url>
</repository>

Unfortunately, when trying to test the decode example, compiling fails with: (this is also same for other jvm-examples from the readme page)

The method buildVerificationChain(CertificateRepository, Clock) in the type DefaultChain is not applicable for the arguments (CertificateRepository)

Next, I tried to build the hcert-kotlin.jar (v 1.4.0-SNAPSHOT) locally using gradle and import and use it in my local maven repository. Unfortunately, I could only generate the hcert-kotlin-jvm.jar (maybe wrong gradle use, please advise). Using this import the compile error is resolved, but a java runtime error about missing kotlin libraries is thrown.

For further reference during my troubleshooting I found issue https://youtrack.jetbrains.com/issue/KT-35716, which could explain the missing correct static java method.

nodh commented 2 years ago

The examples in the Readme have been updated to reflect the current state of the library, as seen in commit 4d9062bff2c3e7d472f4b71ede828de0d87d6799. So for using release 1.3.2, please have a look at https://github.com/ehn-dcc-development/hcert-kotlin/tree/1.3.2

To use it locally, run ./gradlew clean publishToMavenLocal, this will create the artifact ehn.techiop.hcert:hcert-kotlin-jvm:1.4.0-SNAPSHOT (among others). Usage of that artifact in an Java/Gradle project with implementation 'ehn.techiop.hcert:hcert-kotlin-jvm:1.4.0-SNAPSHOT' and the verification example from the Readme works for me. What error are you getting exactly?

nodh commented 2 years ago
package at.example;

import ehn.techiop.hcert.kotlin.chain.CertificateRepository;
import ehn.techiop.hcert.kotlin.chain.Chain;
import ehn.techiop.hcert.kotlin.chain.DecodeResult;
import ehn.techiop.hcert.kotlin.chain.DefaultChain;
import ehn.techiop.hcert.kotlin.chain.Error;
import ehn.techiop.hcert.kotlin.chain.VerificationResult;
import ehn.techiop.hcert.kotlin.chain.impl.PrefilledCertificateRepository;
import ehn.techiop.hcert.kotlin.data.GreenCertificate;

public class Client {

    public static void main(String[] args) throws Exception {
        // Load the certificate from somewhere ...
        String certificatePem = "-----BEGIN CERTIFICATE-----\n" +
                "MIIBvTCCAWOgAwIBAgIKAXk8i88OleLsuTAKBggqhkjOPQQDAjA2MRYwFAYDVQQD\n" +
                "DA1BVCBER0MgQ1NDQSAxMQswCQYDVQQGEwJBVDEPMA0GA1UECgwGQk1TR1BLMB4X\n" +
                "DTIxMDUwNTEyNDEwNloXDTIzMDUwNTEyNDEwNlowPTERMA8GA1UEAwwIQVQgRFND\n" +
                "IDExCzAJBgNVBAYTAkFUMQ8wDQYDVQQKDAZCTVNHUEsxCjAIBgNVBAUTATEwWTAT\n" +
                "BgcqhkjOPQIBBggqhkjOPQMBBwNCAASt1Vz1rRuW1HqObUE9MDe7RzIk1gq4XW5G\n" +
                "TyHuHTj5cFEn2Rge37+hINfCZZcozpwQKdyaporPUP1TE7UWl0F3o1IwUDAOBgNV\n" +
                "HQ8BAf8EBAMCB4AwHQYDVR0OBBYEFO49y1ISb6cvXshLcp8UUp9VoGLQMB8GA1Ud\n" +
                "IwQYMBaAFP7JKEOflGEvef2iMdtopsetwGGeMAoGCCqGSM49BAMCA0gAMEUCIQDG\n" +
                "2opotWG8tJXN84ZZqT6wUBz9KF8D+z9NukYvnUEQ3QIgdBLFSTSiDt0UJaDF6St2\n" +
                "bkUQuVHW6fQbONd731/M4nc=\n" +
                "-----END CERTIFICATE-----";
        CertificateRepository repository = new PrefilledCertificateRepository(certificatePem);
        Chain chain = DefaultChain.buildVerificationChain(repository);

        // Scan the QR code from somewhere ...
        String input = "HC1:NCFRW2EM75VOP10%EHADEW09S7JL5AH/L317E5V3D1R1R6 M*WL194XC9ZOJ%ILVLB+YMS-97RI2J7ZE7%TT TJ5EN3:8RY8L OU42DHNF-0+ SAV3*BTUTRDYJMKKJ%Q+4GQPV+%FOHF.R85 92BH:BTKKIV$AW 0O$T5JJBC0WTA*3EC:JJVOUSG.WJ/ MNOTP30$54LB0*41O52MR4R/AU33PZPL0K**4MFDQ$9M646O1MAH5OU.T4-5AR9TYDDIUOPEKI12*WNQ+6QHM.XNUMNRJO4-7+J6NMIZ13UMHF9K*F7: TBB7HD1000IXS9P3R1BW8BKCOWT1$CILA22:S:AHNMR3T0ITO%12M*H882-DPX$L3JCF1MCNHZDTEBW7V3MS3G$R3HF94K4 UJTJM1V:7B6%BA0I98PB BH977B9D2M10JJO45DF6ZHVCLA/9 MK C5GDCQC9LV4.L3%VS+P4KB40MUZ$6X1L7QOUJFJ%5G.J 4MY-TPW3SDVJG1SETG$VVZA%1GK+CU/N-1V%5NWNKA4W3RPRQNP-H8XRYLCMFVDCT*YVWDL2*QLYUM7WHYVRHL:4WJUA4DH";

        DecodeResult result = chain.decode(input);
        // Read metaInformation like expirationTime, issuedAt, issuer
        VerificationResult verificationResult = result.getVerificationResult();
        boolean isValid = verificationResult.getError() == null;
        // See list below for possible Errors, may be null
        Error error = verificationResult.getError();
        // Result data may be null
        GreenCertificate greenCertificate = result.getChainDecodeResult().getEudgc();

        System.out.println(isValid);
        System.out.println(error);
        System.out.println(greenCertificate);
    }
}
Jopasa commented 2 years ago

@nodh Thank you for your fast response.

regarding gradle after some troubleshooting I could successfully execute the build using the provided command

After some troubleshooting and debugging, I found that the setup works in a simple maven environment, but open switching to spring boot fails. But it only fails when using spring boot maven parent.

That means when using

<parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.3.8.RELEASE</version>
    </parent>

and calling the sample code in a simple RestController it fails with

Exception in thread "main" java.lang.NoSuchMethodError: 'long kotlin.time.Duration$Companion.hours-UwyO8pc(int)'
    at ehn.techiop.hcert.kotlin.chain.impl.DefaultCwtService.<init>(DefaultCwtService.kt:21)
    at ehn.techiop.hcert.kotlin.chain.DefaultChain.buildVerificationChain(DefaultChain.kt:34)
    at ehn.techiop.hcert.kotlin.chain.DefaultChain.buildVerificationChain$default(DefaultChain.kt:30)
    at ehn.techiop.hcert.kotlin.chain.DefaultChain.buildVerificationChain(DefaultChain.kt)
    at at.example.Client.main(Client.java:29)

But when not using spring boot maven parent (iE all versions of needed components explicitly), there is no error. Additionally, I tested both java 11 and 8 compatibility and both java versions work / don't work equally.

This means this is probably due to some spring boot maven magic, but not related to this project.

nodh commented 2 years ago

Maybe upgrading to the latest Spring Boot version 2.5.3 helps?

Jopasa commented 2 years ago

The examples in the Readme have been updated to reflect the current state of the library, as seen in commit 4d9062b. So for using release 1.3.2, please have a look at https://github.com/ehn-dcc-development/hcert-kotlin/tree/1.3.2

To use it locally, run ./gradlew clean publishToMavenLocal, this will create the artifact ehn.techiop.hcert:hcert-kotlin-jvm:1.4.0-SNAPSHOT (among others). Usage of that artifact in an Java/Gradle project with implementation 'ehn.techiop.hcert:hcert-kotlin-jvm:1.4.0-SNAPSHOT' and the verification example from the Readme works for me. What error are you getting exactly?

both versions of the README.md (1.3.2 and the mentioned commit) include the same call

Chain chain = DefaultChain.buildVerificationChain(repository);
Jopasa commented 2 years ago

Maybe upgrading to the latest Spring Boot version 2.5.3 helps?

I am not sure why, but it helped in fact, after upgrading to spring boot version 2.5.3 it works . . .

Jopasa commented 2 years ago

thank you for your help, both README.md versions don't work with 1.3.2 for me, but my problem is resolved using a the new 1.4.0-SNAPSHOT version and looking forward to your next release