Dgraph4j and TLS - Unable to get demo working

Posted by damogallagher:

Hi

I am trying to setup dgraph4j to use TLS.
I have developed a simple maven java project to test this out
My pom contents are simple and are as follows

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0</modelVersion>
	<groupId>com.dgraph</groupId>
	<artifactId>DgraphSample</artifactId>
	<version>0.0.1-SNAPSHOT</version>

	<dependencies>
		<dependency>
			<groupId>io.dgraph</groupId>
			<artifactId>dgraph4j</artifactId>
			<version>20.03.0</version>
		</dependency>
	</dependencies>

</project>

Here is my code

import java.io.File;

import javax.net.ssl.SSLException;

import io.dgraph.DgraphClient;
import io.dgraph.DgraphGrpc;
import io.grpc.ManagedChannel;
import io.grpc.netty.GrpcSslContexts;
import io.grpc.netty.NettyChannelBuilder;
import io.netty.handler.ssl.SslContext;
import io.netty.handler.ssl.SslContextBuilder;

public class Main {

	public static void main(String[] args) {
        try {
            SslContextBuilder builder = GrpcSslContexts.forClient();
            builder.trustManager(new File("src/main/resources/certs/ca.crt"));

            // Skip the next line if you are not performing client verification.
            builder.keyManager(
                    new File("src/main/resources/certs/client.de-dgraph-gcp-.crt"),
                    new File("src/main/resources/certs/client.name.java.key"));
            SslContext sslContext = builder.build();
            
           
            ManagedChannel managedChannel = NettyChannelBuilder.forAddress("myserver.com", 30734)
                    .sslContext(sslContext)
                    .build();
            DgraphGrpc.DgraphStub stub = DgraphGrpc.newStub(managedChannel);
            new DgraphClient(stub);
        } catch (SSLException e) {
            System.out.println("An SSLException has occured. Exception is: " + e);
        }

	}
}

When I run the main method - I get the following stacktrace

SLF4J: Failed to load class "org.slf4j.impl.StaticLoggerBinder".
SLF4J: Defaulting to no-operation (NOP) logger implementation
SLF4J: See http://www.slf4j.org/codes.html#StaticLoggerBinder for further details.
May 13, 2020 3:00:06 PM io.grpc.netty.GrpcSslContexts defaultSslProvider
INFO: Java 9 ALPN API unavailable (this may be normal)
May 13, 2020 3:00:06 PM io.grpc.netty.GrpcSslContexts defaultSslProvider
INFO: netty-tcnative unavailable (this may be normal)
java.lang.ClassNotFoundException: io.netty.internal.tcnative.SSL
	at java.net.URLClassLoader.findClass(URLClassLoader.java:382)
	at java.lang.ClassLoader.loadClass(ClassLoader.java:418)
	at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:355)
	at java.lang.ClassLoader.loadClass(ClassLoader.java:351)
	at java.lang.Class.forName0(Native Method)
	at java.lang.Class.forName(Class.java:348)
	at io.netty.handler.ssl.OpenSsl.<clinit>(OpenSsl.java:121)
	at io.grpc.netty.GrpcSslContexts.defaultSslProvider(GrpcSslContexts.java:228)
	at io.grpc.netty.GrpcSslContexts.configure(GrpcSslContexts.java:155)
	at io.grpc.netty.GrpcSslContexts.forClient(GrpcSslContexts.java:104)
	at Main.main(Main.java:17)

May 13, 2020 3:00:06 PM io.grpc.netty.GrpcSslContexts defaultSslProvider
INFO: Conscrypt not found (this may be normal)
java.lang.ClassNotFoundException: org.conscrypt.Conscrypt
	at java.net.URLClassLoader.findClass(URLClassLoader.java:382)
	at java.lang.ClassLoader.loadClass(ClassLoader.java:418)
	at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:355)
	at java.lang.ClassLoader.loadClass(ClassLoader.java:351)
	at java.lang.Class.forName0(Native Method)
	at java.lang.Class.forName(Class.java:264)
	at io.grpc.internal.ConscryptLoader.newProvider(ConscryptLoader.java:72)
	at io.grpc.netty.GrpcSslContexts$ConscryptHolder.<clinit>(GrpcSslContexts.java:288)
	at io.grpc.netty.GrpcSslContexts.findJdkProvider(GrpcSslContexts.java:261)
	at io.grpc.netty.GrpcSslContexts.defaultSslProvider(GrpcSslContexts.java:232)
	at io.grpc.netty.GrpcSslContexts.configure(GrpcSslContexts.java:155)
	at io.grpc.netty.GrpcSslContexts.forClient(GrpcSslContexts.java:104)
	at Main.main(Main.java:17)

May 13, 2020 3:00:06 PM io.grpc.netty.GrpcSslContexts defaultSslProvider
INFO: Jetty ALPN unavailable (this may be normal)
java.lang.ClassNotFoundException: org/eclipse/jetty/alpn/ALPN
	at java.lang.Class.forName0(Native Method)
	at java.lang.Class.forName(Class.java:348)
	at io.grpc.netty.JettyTlsUtil.isJettyAlpnConfigured(JettyTlsUtil.java:64)
	at io.grpc.netty.GrpcSslContexts.findJdkProvider(GrpcSslContexts.java:252)
	at io.grpc.netty.GrpcSslContexts.defaultSslProvider(GrpcSslContexts.java:232)
	at io.grpc.netty.GrpcSslContexts.configure(GrpcSslContexts.java:155)
	at io.grpc.netty.GrpcSslContexts.forClient(GrpcSslContexts.java:104)
	at Main.main(Main.java:17)

Exception in thread "main" java.lang.IllegalStateException: Could not find TLS ALPN provider; no working netty-tcnative, Conscrypt, or Jetty NPN/ALPN available
	at io.grpc.netty.GrpcSslContexts.defaultSslProvider(GrpcSslContexts.java:244)
	at io.grpc.netty.GrpcSslContexts.configure(GrpcSslContexts.java:155)
	at io.grpc.netty.GrpcSslContexts.forClient(GrpcSslContexts.java:104)
	at Main.main(Main.java:17)

Is there anything else I need to do? I have been following the dgraph4j documentation

Thanks
Damien

danielmai commented :

Does the server certificate hostname match the server’s hostname (i.e., myserver.com in your example code).

damogallagher commented :

@danielmai it does yes- even if I comment out the cert piece, the same error is thrown. Should the draph4j lib pull in all dependencies it requires?

danielmai commented :

INFO: Java 9 ALPN API unavailable (this may be normal)
java.lang.ClassNotFoundException: io.netty.internal.tcnative.SSL
java.lang.ClassNotFoundException: org.conscrypt.Conscrypt
java.lang.ClassNotFoundException: org/eclipse/jetty/alpn/ALPN
Could not find TLS ALPN provider; no working netty-tcnative, Conscrypt, or Jetty NPN/ALPN available

What platform and Java version are you using? Is this with the latest JDK (Java 14)? Looks like your setup doesn’t have any of the ALPN providers. You need at least one to handle the TLS connections with gRPC. See gprc-java’s SECURITY.md page for more info on the TLS setup.

damogallagher commented :

That was it - I was using Java 8. The documentation references to use Java 1.8.x for any versions of Dgraph4j greater than version 1.1.0.
I have tried with Java 11 and Java 14 and it is working now

Many thanks for your help on this issue