Skip to content

Commit

Permalink
When no JAX-B RI on CP warn and disable WADL
Browse files Browse the repository at this point in the history
Signed-off-by: Jan Supol <[email protected]>
  • Loading branch information
jansupol committed Apr 29, 2020
1 parent 519879c commit f9a8431
Show file tree
Hide file tree
Showing 8 changed files with 150 additions and 14 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
import java.util.Locale;
import java.util.Map;
import java.util.Set;
import java.util.logging.Logger;

import javax.ws.rs.RuntimeType;
import javax.ws.rs.ext.MessageBodyReader;
Expand All @@ -30,6 +31,7 @@
import javax.inject.Singleton;

import org.glassfish.jersey.CommonProperties;
import org.glassfish.jersey.internal.LocalizationMessages;
import org.glassfish.jersey.internal.ServiceFinderBinder;
import org.glassfish.jersey.internal.inject.AbstractBinder;
import org.glassfish.jersey.internal.util.ReflectionHelper;
Expand All @@ -45,6 +47,8 @@
*/
public final class MessagingBinders {

private static final Logger LOGGER = Logger.getLogger(MessagingBinders.class.getName());

/**
* Prevents instantiation.
*/
Expand Down Expand Up @@ -213,6 +217,22 @@ private void bindToBinder(AbstractBinder binder) {
break;
}
providerBinder.bind(binder, provider);
} else {
switch (provider) {
case DOMSOURCE:
case SAXSOURCE:
case STREAMSOURCE:
LOGGER.warning(LocalizationMessages.DEPENDENT_CLASS_OF_DEFAULT_PROVIDER_NOT_FOUND(provider.className,
"MessageBodyReader<" + provider.className + ">")
);
break;
case RENDEREDIMAGE:
case SOURCE:
LOGGER.warning(LocalizationMessages.DEPENDENT_CLASS_OF_DEFAULT_PROVIDER_NOT_FOUND(provider.className,
"MessageBodyWriter<" + provider.className + ">")
);
break;
}
}
}
}
Expand All @@ -226,36 +246,36 @@ private interface ProviderBinder {
void bind(AbstractBinder binder, Provider provider);
}

private class DomSourceBinder implements ProviderBinder {
private static class DomSourceBinder implements ProviderBinder {
@Override
public void bind(AbstractBinder binder, Provider provider) {
binder.bind(SourceProvider.DomSourceReader.class).to(MessageBodyReader.class).in(Singleton.class);
}
}

private class RenderedImageBinder implements ProviderBinder {
private static class RenderedImageBinder implements ProviderBinder {
@Override
public void bind(AbstractBinder binder, Provider provider) {
binder.bind(RenderedImageProvider.class)
.to(MessageBodyReader.class).to(MessageBodyWriter.class).in(Singleton.class);
}
}

private class SaxSourceBinder implements ProviderBinder {
private static class SaxSourceBinder implements ProviderBinder {
@Override
public void bind(AbstractBinder binder, Provider provider) {
binder.bind(SourceProvider.SaxSourceReader.class).to(MessageBodyReader.class).in(Singleton.class);
}
}

private class SourceBinder implements ProviderBinder {
private static class SourceBinder implements ProviderBinder {
@Override
public void bind(AbstractBinder binder, Provider provider) {
binder.bind(SourceProvider.SourceWriter.class).to(MessageBodyWriter.class).in(Singleton.class);
}
}

private class StreamSourceBinder implements ProviderBinder {
private static class StreamSourceBinder implements ProviderBinder {
@Override
public void bind(AbstractBinder binder, Provider provider) {
binder.bind(SourceProvider.StreamSourceReader.class).to(MessageBodyReader.class).in(Singleton.class);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
#
# Copyright (c) 2012, 2019 Oracle and/or its affiliates. All rights reserved.
# Copyright (c) 2012, 2020 Oracle and/or its affiliates. All rights reserved.
# Copyright (c) 2018 Payara Foundation and/or its affiliates.
#
# This program and the accompanying materials are made available under the
Expand Down Expand Up @@ -32,6 +32,7 @@ cookie.is.null=Cookie is null.
date.is.null=Date is null.
dependent.class.of.provider.format.error={0}. A dependent class of the class {1} implementing the provider {2} is malformed. The provider implementation is ignored. Check if the malformed class is part of a stubbed jar that used for compiling only.
dependent.class.of.provider.not.found=A dependent class, {0}, of the class {1} implementing the provider {2} is not found. The provider implementation is ignored.
dependent.class.of.default.provider.not.found=A class {0} for a default provider {1} was not found. The provider is not available.
entity.tag.is.null=Entity tag is null.
error.caught.while.loading.spi.providers=Error caught while loading SPI providers.
error.entity.stream.closed=Entity input stream has already been closed.
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2013, 2018 Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2013, 2020 Oracle and/or its affiliates. All rights reserved.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0, which is available at
Expand All @@ -20,14 +20,19 @@
import javax.ws.rs.core.FeatureContext;

import javax.inject.Singleton;
import javax.xml.bind.JAXBException;

import org.glassfish.jersey.internal.inject.AbstractBinder;
import org.glassfish.jersey.internal.util.PropertiesHelper;
import org.glassfish.jersey.server.ServerProperties;
import org.glassfish.jersey.server.internal.LocalizationMessages;
import org.glassfish.jersey.server.model.ModelProcessor;
import org.glassfish.jersey.server.wadl.internal.WadlApplicationContextImpl;
import org.glassfish.jersey.server.wadl.internal.generators.WadlGeneratorJAXBGrammarGenerator;
import org.glassfish.jersey.server.wadl.processor.WadlModelProcessor;

import java.util.logging.Logger;


/**
* Feature enabling WADL processing. The feature registers providers and binders needed to enable wadl in the
Expand All @@ -38,6 +43,8 @@
*/
public class WadlFeature implements Feature {

private static final Logger LOGGER = Logger.getLogger(WadlFeature.class.getName());

@Override
public boolean configure(FeatureContext context) {
final boolean disabled = PropertiesHelper.isProperty(context.getConfiguration().getProperty(ServerProperties
Expand All @@ -46,6 +53,11 @@ public boolean configure(FeatureContext context) {
return false;
}

if (!isJaxB()) {
LOGGER.warning(LocalizationMessages.WADL_FEATURE_DISABLED());
return false;
}

context.register(WadlModelProcessor.class);
context.register(new AbstractBinder() {
@Override
Expand All @@ -56,4 +68,12 @@ protected void configure() {

return true;
}

private static boolean isJaxB() {
try {
return null != WadlApplicationContextImpl.getJAXBContextFromWadlGenerator(new WadlGeneratorJAXBGrammarGenerator());
} catch (JAXBException je) {
return false;
}
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2010, 2018 Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2010, 2020 Oracle and/or its affiliates. All rights reserved.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0, which is available at
Expand Down Expand Up @@ -94,7 +94,15 @@ public WadlApplicationContextImpl(
// create a temporary generator just to do this one task
final WadlGenerator wadlGenerator = wadlGeneratorConfig.createWadlGenerator(injectionManager);

JAXBContext jaxbContextCandidate;
try {
jaxbContext = getJAXBContextFromWadlGenerator(wadlGenerator);
} catch (JAXBException ex) {
throw new ProcessingException(LocalizationMessages.ERROR_WADL_JAXB_CONTEXT(), ex);
}
}

public static JAXBContext getJAXBContextFromWadlGenerator(WadlGenerator wadlGenerator) throws JAXBException {
JAXBContext jaxbContextCandidate = null;

final ClassLoader contextClassLoader = AccessController.doPrivileged(ReflectionHelper.getContextClassLoaderPA());
try {
Expand All @@ -117,13 +125,13 @@ public WadlApplicationContextImpl(
LOGGER.log(Level.FINE, LocalizationMessages.WADL_JAXB_CONTEXT_FALLBACK(), ex);
jaxbContextCandidate = JAXBContext.newInstance(wadlGenerator.getRequiredJaxbContextPath());
} catch (final JAXBException innerEx) {
throw new ProcessingException(LocalizationMessages.ERROR_WADL_JAXB_CONTEXT(), ex);
throw ex;
}
} finally {
AccessController.doPrivileged(ReflectionHelper.setContextClassLoaderPA(contextClassLoader));
}

jaxbContext = jaxbContextCandidate;
return jaxbContextCandidate;
}

@Override
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
#
# Copyright (c) 2012, 2018 Oracle and/or its affiliates. All rights reserved.
# Copyright (c) 2012, 2020 Oracle and/or its affiliates. All rights reserved.
#
# This program and the accompanying materials are made available under the
# terms of the Eclipse Public License v. 2.0, which is available at
Expand Down Expand Up @@ -185,6 +185,7 @@ unsupported.uri.injection.type="@Uri"-based injection of "{0}" type is not suppo
user.not.authorized=User not authorized.
wadl.doc.extended.wadl=This is full WADL including extended resources. To get simplified WADL with users resources only do not use the query parameter {0}. Link: {1}
wadl.doc.simple.wadl=This is simplified WADL with user and core resources only. To get full WADL with extended resources use the query parameter {0}. Link: {1}
wadl.feature.disabled=JAXBContext implementation could not be found. WADL feature is disabled.
wadl.jaxb.context.fallback=Error creating a JAXBContext for wadl serialization. Trying a fallback solution for osgi environments.
wadl.resourcedoc.ambiguous.method.entries=Ambiguous resource documentation detected: \
Unique resource method documentation cannot be found for method %{0}.%{1}%{2}. \
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
//
// Copyright (c) 2014, 2018 Oracle and/or its affiliates. All rights reserved.
// Copyright (c) 2014, 2020 Oracle and/or its affiliates. All rights reserved.
//
// This program and the accompanying materials are made available under the
// terms of the Eclipse Distribution License v. 1.0, which is available at
Expand All @@ -13,6 +13,7 @@ allow { [org.osgi.service.condpermadmin.BundleLocationCondition "*System*"] (org
allow { [org.osgi.service.condpermadmin.BundleLocationCondition "*additional-bundle*"] (java.security.AllPermission) } "allToAdditional";
allow { [org.osgi.service.condpermadmin.BundleLocationCondition "*javassist*"] (java.security.AllPermission) } "allToJavassist";
allow { [org.osgi.service.condpermadmin.BundleLocationCondition "*jakarta.ws.rs*"] (java.security.AllPermission) } "allToJavaxWsRs";
allow { [org.osgi.service.condpermadmin.BundleLocationCondition "*jakarta.xml.bind*"] (java.security.AllPermission) } "allToJaxB";
allow { [org.osgi.service.condpermadmin.BundleLocationCondition "*jetty*"] (java.security.AllPermission) } "allToJetty";
allow { [org.osgi.service.condpermadmin.BundleLocationCondition "*hk2*"] (java.security.AllPermission) } "allToHk2";
allow { [org.osgi.service.condpermadmin.BundleLocationCondition "*osgi*"] (java.security.AllPermission) } "allToOsgi";
Expand All @@ -36,6 +37,7 @@ allow { [org.osgi.service.condpermadmin.BundleLocationCondition "*jersey-common*
allow { [org.osgi.service.condpermadmin.BundleLocationCondition "*jersey-common*"] (java.lang.RuntimePermission "accessClassInPackage.sun.misc") } "accessClassInPackageSunMisc";
allow { [org.osgi.service.condpermadmin.BundleLocationCondition "*jersey-common*"] (java.lang.RuntimePermission "getClassLoader") } "getCLToJerseyCommon";
allow { [org.osgi.service.condpermadmin.BundleLocationCondition "*jersey-common*"] (java.lang.RuntimePermission "modifyThread") } "modifyThreadToJerseyCommon";
allow { [org.osgi.service.condpermadmin.BundleLocationCondition "*jersey-common*"] (java.lang.RuntimePermission "setContextClassLoader") } "setContextCLToJerseyCommon";
allow { [org.osgi.service.condpermadmin.BundleLocationCondition "*jersey-common*"] (java.util.PropertyPermission "*" "read") } "propReadToJerseyCommon";
allow { [org.osgi.service.condpermadmin.BundleLocationCondition "*jersey-common*"] (java.io.FilePermission "<<ALL FILES>>" "read,write") } "fileReadToJerseyCommon";
allow { [org.osgi.service.condpermadmin.BundleLocationCondition "*jersey-client*"] (java.security.AllPermission) } "allToJerseyClient";
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2013, 2018 Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2013, 2020 Oracle and/or its affiliates. All rights reserved.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0, which is available at
Expand Down Expand Up @@ -44,6 +44,7 @@

import org.glassfish.jersey.logging.LoggingFeature;
import org.glassfish.jersey.server.ResourceConfig;
import org.glassfish.jersey.server.ServerProperties;
import org.glassfish.jersey.test.JerseyTest;
import org.glassfish.jersey.test.TestProperties;

Expand Down Expand Up @@ -399,6 +400,7 @@ protected Application configure() {
return new ResourceConfig(MyResource.class)
.property(LoggingFeature.LOGGING_FEATURE_LOGGER_NAME, LOGGER_NAME)
.property(LoggingFeature.LOGGING_FEATURE_LOGGER_LEVEL, "INFO")
.property(ServerProperties.WADL_FEATURE_DISABLE, true)
.register(CustomFilter.class);
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
/*
* Copyright (c) 2020 Oracle and/or its affiliates. All rights reserved.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0, which is available at
* http://www.eclipse.org/legal/epl-2.0.
*
* This Source Code may also be made available under the following Secondary
* Licenses when the conditions for such availability set forth in the
* Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
* version 2 with the GNU Classpath Exception, which is available at
* https://www.gnu.org/software/classpath/license.html.
*
* SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
*/

package org.glassfish.jersey.tests.e2e.server.wadl;

import org.glassfish.jersey.internal.ServiceFinder;
import org.glassfish.jersey.internal.util.JdkVersion;
import org.glassfish.jersey.message.internal.MediaTypes;
import org.glassfish.jersey.server.ResourceConfig;
import org.glassfish.jersey.server.internal.LocalizationMessages;
import org.glassfish.jersey.test.JerseyTest;
import org.junit.AfterClass;
import org.junit.Assert;
import org.junit.BeforeClass;
import org.junit.Test;

import javax.ws.rs.PUT;
import javax.ws.rs.Path;
import javax.ws.rs.core.Application;
import javax.ws.rs.core.HttpHeaders;
import javax.ws.rs.core.Response;
import java.io.ByteArrayOutputStream;
import java.io.OutputStream;
import java.io.PrintStream;

public class NoJAXBNoWadlTest extends JerseyTest {

private static PrintStream errorStream;
private static OutputStream readableStream = new ByteArrayOutputStream(800);

@BeforeClass
public static void before() {
errorStream = System.err;
System.setErr(new PrintStream(readableStream));
}

@AfterClass
public static void after() {
System.setErr(errorStream);
}

@Path("dummy")
public static class NoJAXBNoWadlDummyResource {
@PUT
public String put(String put) {
return "OK";
}
}

@Override
protected Application configure() {
return new ResourceConfig(NoJAXBNoWadlDummyResource.class);
}

@Test
public void testOptionsNoWadl() {
final boolean shouldHaveJaxb = JdkVersion.getJdkVersion().getMajor() == 1;

// Make sure the test does not have JAX-B on a classpath
Assert.assertFalse(ServiceFinder.find("javax.xml.bind.JAXBContext").iterator().hasNext());

try (Response r = target("dummy").request(MediaTypes.WADL_TYPE).options()) {
String headers = r.getHeaderString(HttpHeaders.ALLOW);
Assert.assertEquals("OPTIONS,PUT", headers);
}
System.out.println(readableStream.toString());
Assert.assertEquals(!shouldHaveJaxb, readableStream.toString().contains(LocalizationMessages.WADL_FEATURE_DISABLED()));
}
}

0 comments on commit f9a8431

Please sign in to comment.