web-push-libs / webpush-java

Web Push library for Java
MIT License
318 stars 112 forks source link

Getting Error - java.lang.NoClassDefFoundError: org/bouncycastle/jce/provider/BouncyCastleProvider #89

Closed aaravrahul3268 closed 5 years ago

aaravrahul3268 commented 5 years ago

Hello.

I am trying to use webpush-java with a web page and I created a Java play application (Jar file) to try it. It works fine in my local Windows Machine and i am able to push notification and i get notification in the browser. But When i deploy it on Centos Os Server I get this error 👎 java.lang.NoClassDefFoundError: org/bouncycastle/jce/provider/BouncyCastleProvider

Please find my attached code below.

    public ServiceResult sendNotification(NotificationInput input) {

//      if (Security.getProvider(BouncyCastleProvider.PROVIDER_NAME) == null) {
//          System.out.println("11111111111111111");
//          System.out.println(Security.getProvider(BouncyCastleProvider.PROVIDER_NAME));
//            Security.addProvider(new BouncyCastleProvider());
//      }
//      Security.removeProvider(BouncyCastleProvider.PROVIDER_NAME);
//      Security.addProvider(new BouncyCastleProvider());

        Security.removeProvider(BouncyCastleProvider.PROVIDER_NAME);
        Security.addProvider(new BouncyCastleProvider());
        try {

        //  Security.addProvider(new BouncyCastleProvider());
            Notification notification;
            HttpResponse httpResponse;

            PushService pushService = new PushService(PUBLIC_KEY, PRIVATE_KEY, SUBJECT);
            final String payload = getPayloadString(input);

            System.out.println("payload is " + payload);
            List<Subscription> subscriptionList = getSubscriptionList();
            if (subscriptionList != null) {

                for (Subscription subscription : subscriptionList) {
                    notification = new Notification(subscription, payload);
                    httpResponse = pushService.send(notification);
                    System.out.println(httpResponse.getStatusLine().getReasonPhrase());
                    System.out.println("dfdfdfdfdfdfdfdfdfdfdfdfdfdfdfdfdfdfdfdfdfdf");
                    int statusCode = httpResponse.getStatusLine().getStatusCode();

                    System.out.println("String.valueOfstatusCode  " + statusCode);

                }

            }
            return createServiceResult(SERVICE_SUCCESS);

        } catch (Exception e) {
            e.printStackTrace();
        }
        return createServiceResult(FAILURE_STATUS);
    } 
martijndwars commented 5 years ago

This library uses BouncyCastle to perform cryptographic operations. The BouncyCastle JAR needs the JCA signature for the JVM to trust it as a cryptography provider. However, dealing with signed dependencies brings some complications.

One complication is that you cannot create a fat JAR/shadow JAR/uber JAR, because when you move the BouncyCastle classes to the shadow JAR you lose the signature. You cannot include the BouncyCastle JAR inside your own JAR either, because the JVM cannot load classes in nested JARs.

The best way to work around this is to add BouncyCastle to the classpath yourself. E.g. if you would run your Java application as java -cp my-application.jar com.acme.Main, you should now run it as java -cp my-application.jar:bcprov-jdk15on-154.jar com.acme.Main. You can download bcprov-jdk15on-154.jar manually here. If you use a build tool like Gradle, you can have Gradle fetch this JAR and add it to the classpath for you.