问题
I am writing a rest client using java.net which should do a PATCH request. But as PATCH is not a supported method in java.net, I used reflection to make it supported by changing the code like
private void updateConnectionToSupportPatchRequest(final HttpURLConnection conn)
throws ReflectiveOperationException {
try {
final Object targetConn;
if (conn instanceof HttpsURLConnectionImpl) {
final Field delegateField = HttpsURLConnectionImpl.class.getDeclaredField("delegate");
delegateField.setAccessible(true);
targetConn = delegateField.get(conn);
} else {
targetConn = conn;
}
final Field methodField = HttpURLConnection.class.getDeclaredField("method");
methodField.setAccessible(true);
methodField.set(targetConn, "PATCH");
} catch (final NoSuchFieldException ex) {
LOGGER.error("NoSuchFieldException: {} ", ex.getMessage());
}
}
but when I deploy my application which uses my rest client in JBoss, I get this error -
java.lang.NoClassDefFoundError: sun/net/www/protocol/https/HttpsURLConnectionImpl
I looked up on this error and came across this post http://planet.jboss.org/post/dealing_with_sun_jdk_related_noclassdeffounderror_under_jboss
I tried the suggested solution in the post still getting the same error. Any ideas on how to get passed this issue?
P.S. I cannot use the Apache HttpClient or RestEasy(Jboss) as there is another 3PP being used in the project which does not support Apache HttpClient
回答1:
Have you tried using the workaround X-HTTP-Method-Override before trying to fiddle with internal classes of the JDK? If that's the case, you can use the instance's getClass
-method to access fields and use isAssignableFrom
as alternative to instanceof
.
Another approach to get rid off specifying concrete classes is just trying to get the field in HttpsURLConnection
and assuming a non-Https-URLConnection if the field can't be found. This might look like the following code:
private void updateConnectionToSupportPatchRequest(final HttpURLConnection conn)
throws ReflectiveOperationException {
try {
final Object targetConn = conn;
try {
final Field delegateField = findField(conn.getClass(), "delegate");
delegateField.setAccessible(true);
targetConn = delegateField.get(conn);
}
catch(NoSuchFieldException nsfe) {
// no HttpsURLConnection
}
final Field methodField = findField(conn.getClass(), "method");
methodField.setAccessible(true);
methodField.set(targetConn, "PATCH");
} catch (final NoSuchFieldException ex) {
LOGGER.error("NoSuchFieldException: {} ", ex.getMessage());
}
}
private Field findField(Class clazz, String name) throws NoSuchFieldException {
while (clazz != null) {
try {
return clazz.getDeclaredField(name);
}
catch(NoSuchFieldException nsfe) {
// ignore
}
clazz = clazz.getSuperclass();
}
throw new NoSuchFieldException(name);
}
But this might fail at another level because - obviously - the class that is used within JBoss is not the one you implemented the workaround, so fields and methods might be named differently.
来源:https://stackoverflow.com/questions/47135808/getting-error-java-lang-noclassdeffounderror-sun-net-www-protocol-https-httpsur