Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

NoSuchMethodError newSSL when running under tomcat #5648

Closed
brharrington opened this issue Aug 5, 2016 · 15 comments
Closed

NoSuchMethodError newSSL when running under tomcat #5648

brharrington opened this issue Aug 5, 2016 · 15 comments
Assignees
Labels
Milestone

Comments

@brharrington
Copy link

This might be related to #5423 or #5539, but it isn't clear to me if either of those are the same issue. We have an application with a netty client running under tomcat (7.0.59) and tomcat is using the tomcat native listener:

Aug 05, 2016 3:18:19 PM org.apache.catalina.core.AprLifecycleListener lifecycleEvent
INFO: Loaded APR based Apache Tomcat Native library 1.1.32 using APR version 1.5.1.

This was working fine with netty-4.1.0.Beta8. When trying to update to 4.1.3.Final we started getting a failure for the netty client when trying to hit an SSL endpoint:

java.lang.NoSuchMethodError: org.apache.tomcat.jni.SSL.newSSL(JZ)J
    at io.netty.handler.ssl.OpenSsl.<clinit>(OpenSsl.java:131) ~[netty-handler-4.1.3.Final.jar:4.1.3.Final]
    at io.netty.handler.ssl.SslContext.defaultProvider(SslContext.java:115) ~[netty-handler-4.1.3.Final.jar:4.1.3.Final]
    at io.netty.handler.ssl.SslContext.defaultClientProvider(SslContext.java:111) ~[netty-handler-4.1.3.Final.jar:4.1.3.Final]
    at io.netty.handler.ssl.SslContext.newClientContextInternal(SslContext.java:741) ~[netty-handler-4.1.3.Final.jar:4.1.3.Final]
    at io.netty.handler.ssl.SslContext.newClientContext(SslContext.java:721) ~[netty-handler-4.1.3.Final.jar:4.1.3.Final]
    at io.netty.handler.ssl.SslContext.newClientContext(SslContext.java:671) ~[netty-handler-4.1.3.Final.jar:4.1.3.Final]
    at io.netty.handler.ssl.SslContext.newClientContext(SslContext.java:604) ~[netty-handler-4.1.3.Final.jar:4.1.3.Final]
    at io.netty.handler.ssl.SslContext.newClientContext(SslContext.java:458) ~[netty-handler-4.1.3.Final.jar:4.1.3.Final]

That method doesn't exist in the tomcat-native version that comes with tomcat until version 1.2 and we have 1.1.32. When running with 4.1.0.Beta8, it failed to use openssl and would fall back to the default implementation:

2016-08-05T15:32:41.392 DEBUG [pool-54-thread-21] io.netty.handler.ssl.OpenSsl: Failed to load netty-tcnative; OpenSslEngine will be unavailable. See http://netty.io/wiki/forked-tomcat-native.html for more information.
    at io.netty.handler.ssl.OpenSsl.<clinit>(OpenSsl.java:58) [netty-handler-4.1.0.Beta8.jar:4.1.0.Beta8]
    at io.netty.handler.ssl.SslContext.defaultProvider(SslContext.java:111) [netty-handler-4.1.0.Beta8.jar:4.1.0.Beta8]
    at io.netty.handler.ssl.SslContext.defaultClientProvider(SslContext.java:107) [netty-handler-4.1.0.Beta8.jar:4.1.0.Beta8]
    at io.netty.handler.ssl.SslContext.newClientContextInternal(SslContext.java:735) [netty-handler-4.1.0.Beta8.jar:4.1.0.Beta8]
    at io.netty.handler.ssl.SslContext.newClientContext(SslContext.java:715) [netty-handler-4.1.0.Beta8.jar:4.1.0.Beta8]
    at io.netty.handler.ssl.SslContext.newClientContext(SslContext.java:666) [netty-handler-4.1.0.Beta8.jar:4.1.0.Beta8]
    at io.netty.handler.ssl.SslContext.newClientContext(SslContext.java:599) [netty-handler-4.1.0.Beta8.jar:4.1.0.Beta8]
@Scottmitch
Copy link
Member

what version of netty-tcnative are you using?

@brharrington
Copy link
Author

I'm not using netty-tcnative. It is finding the org.apache.tomcat.jni.SSL class because tomcat has it.

@brharrington
Copy link
Author

A few more observations:

  • 4.1.0.CR4 is the first version where we see it start to fail in this way.
  • If I include netty-tcnative-boringssl-static in the classpath, then tomcat seems to use the org.apache.tomcat.jni.SSL class from tcnative instead of the one in tomcat-native provided by the container and it no longer fails. (for my test tcnative version 1.1.33.Fork19)

I think I can explicitly include netty-tcnative-boringssl-static as a workaround, but it would be nice if the fall back behavior would work as it did prior to 4.1.0.CR4.

@Scottmitch
Copy link
Member

we plan to put netty-tcnative into different package/namespace and I expect the problem should be resolved at that point.

@brharrington
Copy link
Author

I looked at it some more to get a better idea of what it was doing. The problem seems to be from 379ad2c. The load is failing, but it looks like what tomcat is providing causes the initialize to succeed. So it is getting by the checks and then failing with a NoSuchMethodError on org.apache.tomcat.jni.SSL.

Changing the package would work for my use-case. However, reading through netty/netty-tcnative#136 it seems there are some additional complications for users that need tcnative.

For my immediate use-case I was also able to get it to work by adding an additional sanity check:

diff --git a/handler/src/main/java/io/netty/handler/ssl/OpenSsl.java b/handler/src/main/java/io/netty/handler/ssl/OpenSsl.java
index a151670..14ea5d9 100644
--- a/handler/src/main/java/io/netty/handler/ssl/OpenSsl.java
+++ b/handler/src/main/java/io/netty/handler/ssl/OpenSsl.java
@@ -78,12 +78,18 @@ public final class OpenSsl {

         // Test if netty-tcnative is in the classpath first.
         try {
-            Class.forName("org.apache.tomcat.jni.SSL", false, OpenSsl.class.getClassLoader());
+            Class<?> cls = Class.forName("org.apache.tomcat.jni.SSL", false, OpenSsl.class.getClassLoader());
+            cls.getMethod("newSSL", long.class, boolean.class);
         } catch (ClassNotFoundException t) {
             cause = t;
             logger.debug(
                     "netty-tcnative not in the classpath; " +
                     OpenSslEngine.class.getSimpleName() + " will be unavailable.");
+        } catch (NoSuchMethodException t) {
+            cause = t;
+            logger.debug(
+                    "incompatible org.apache.tomcat.jni.SSL in the classpath; " +
+                    OpenSslEngine.class.getSimpleName() + " will be unavailable.");
         }

         // If in the classpath, try to load the native library and initialize netty-tcnative.

Is there any ETA on the package name change? Is it worthwhile sending a PR for the workaround above in the mean time?

@normanmaurer
Copy link
Member

No eta and yes a pr would be awesome

Am 06.08.2016 um 18:12 schrieb brharrington notifications@github.com:

I looked at it some more to get a better idea of what it was doing. The problem seems to be from 379ad2c. The load is failing, but it looks like what tomcat is providing causes the initialize to succeed. So it is getting by the checks and then failing with a NoSuchMethodError on org.apache.tomcat.jni.SSL.

Changing the package would work for my use-case. However, reading through netty/netty-tcnative#136 it seems there are some additional complications for users that need tcnative.

For my immediate use-case I was also able to get it to work by adding an additional sanity check:

diff --git a/handler/src/main/java/io/netty/handler/ssl/OpenSsl.java b/handler/src/main/java/io/netty/handler/ssl/OpenSsl.java
index a151670..14ea5d9 100644
--- a/handler/src/main/java/io/netty/handler/ssl/OpenSsl.java
+++ b/handler/src/main/java/io/netty/handler/ssl/OpenSsl.java
@@ -78,12 +78,18 @@ public final class OpenSsl {

     // Test if netty-tcnative is in the classpath first.
     try {
  •        Class.forName("org.apache.tomcat.jni.SSL", false, OpenSsl.class.getClassLoader());
    
  •        Class<?> cls = Class.forName("org.apache.tomcat.jni.SSL", false, OpenSsl.class.getClassLoader());
    
  •        cls.getMethod("newSSL", long.class, boolean.class);
     } catch (ClassNotFoundException t) {
         cause = t;
         logger.debug(
                 "netty-tcnative not in the classpath; " +
                 OpenSslEngine.class.getSimpleName() + " will be unavailable.");
    
  •    } catch (NoSuchMethodException t) {
    
  •        cause = t;
    
  •        logger.debug(
    
  •                "incompatible org.apache.tomcat.jni.SSL in the classpath; " +
    
  •                OpenSslEngine.class.getSimpleName() + " will be unavailable.");
     }
    
     // If in the classpath, try to load the native library and initialize netty-tcnative.
    

    Is there any ETA on the package name change? Is it worthwhile sending a PR for the workaround above in the mean time?


You are receiving this because you are subscribed to this thread.
Reply to this email directly, view it on GitHub, or mute the thread.

@normanmaurer
Copy link
Member

@brharrington Let me just take care of it for you... Thanks for the tip!

@normanmaurer
Copy link
Member

@brharrington or if you like you can also submit the PR for fame an profit ;) Just let me know what you prefer.

@normanmaurer
Copy link
Member

Also I think this will most likely not work with later versions of tomcat as they added the same method:
https://github.com/apache/tomcat-native/blob/trunk/native/src/ssl.c#L1224

Let me think about a better way to work around it.

@normanmaurer
Copy link
Member

@brharrington ok I think I have an idea... stay tuned

@normanmaurer normanmaurer added this to the 4.0.41.Final milestone Aug 6, 2016
normanmaurer added a commit that referenced this issue Aug 10, 2016
Motivation:

If netty is used in a tomcat container tomcat itself may ship tcnative. Because of this we will try to use OpenSsl in netty and fail because it is different to netty-tcnative.

Modifications:

Ensure if we find tcnative it is really netty-tcnative before using it.

Result:

No more problems when using netty in a tomcat container that also has tcnative installed.
normanmaurer added a commit that referenced this issue Aug 11, 2016
Motivation:

If netty is used in a tomcat container tomcat itself may ship tcnative. Because of this we will try to use OpenSsl in netty and fail because it is different to netty-tcnative.

Modifications:

Ensure if we find tcnative it is really netty-tcnative before using it.

Result:

No more problems when using netty in a tomcat container that also has tcnative installed.
normanmaurer added a commit that referenced this issue Aug 11, 2016
Motivation:

If netty is used in a tomcat container tomcat itself may ship tcnative. Because of this we will try to use OpenSsl in netty and fail because it is different to netty-tcnative.

Modifications:

Ensure if we find tcnative it is really netty-tcnative before using it.

Result:

No more problems when using netty in a tomcat container that also has tcnative installed.
normanmaurer added a commit that referenced this issue Aug 11, 2016
Motivation:

If netty is used in a tomcat container tomcat itself may ship tcnative. Because of this we will try to use OpenSsl in netty and fail because it is different to netty-tcnative.

Modifications:

Ensure if we find tcnative it is really netty-tcnative before using it.

Result:

No more problems when using netty in a tomcat container that also has tcnative installed.
@normanmaurer
Copy link
Member

Work around by #5666

@normanmaurer normanmaurer self-assigned this Aug 11, 2016
@brharrington
Copy link
Author

Great, thanks for the quick turn around.

@nickmahilani
Copy link

any ETA on the next 4.1.x release with this fix? We have a couple apps that we would like to upgrade from Netty 4.1.0.Beta8 to 4.1.x.Final once this fix is released.

@normanmaurer
Copy link
Member

Next week

Am 12.08.2016 um 19:02 schrieb Nick Mahilani notifications@github.com:

any ETA on the next 4.1.x release with this fix? We have a couple apps that we would like to upgrade from Netty 4.1.0.Beta8 to 4.1.x.Final once this fix is released.


You are receiving this because you were assigned.
Reply to this email directly, view it on GitHub, or mute the thread.

@nickmahilani
Copy link

sounds good. thanks !

liuzhengyang pushed a commit to liuzhengyang/netty that referenced this issue Sep 10, 2017
Motivation:

If netty is used in a tomcat container tomcat itself may ship tcnative. Because of this we will try to use OpenSsl in netty and fail because it is different to netty-tcnative.

Modifications:

Ensure if we find tcnative it is really netty-tcnative before using it.

Result:

No more problems when using netty in a tomcat container that also has tcnative installed.
pulllock pushed a commit to pulllock/netty that referenced this issue Oct 19, 2023
Motivation:

If netty is used in a tomcat container tomcat itself may ship tcnative. Because of this we will try to use OpenSsl in netty and fail because it is different to netty-tcnative.

Modifications:

Ensure if we find tcnative it is really netty-tcnative before using it.

Result:

No more problems when using netty in a tomcat container that also has tcnative installed.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

4 participants