You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@cxf.apache.org by Sergey Beryozkin <sb...@gmail.com> on 2014/04/01 11:46:21 UTC

Re: git commit: [CXF-5661]add more JMX operations for ManagedEndpoint mbean

Hi Freeman

IMHO it appears to be a rather 'intrusive' commit. I'm sure it will help 
with the JMX improvements work somehow but here are some comments:

Here are some comments:
- should your bean annotation introspectors to do with JMX be moved to 
rt/management, do they belong to the core ? All these Jackson deps just 
hit the eye :-), nothing against Jackson here per se, just seems it is 
not in the right place
- AbstractJAXRSFactoryBean update: I don't think we need to keep the 
custom classes map within every created endpoint by default for the sake 
of the optional JMX improvement: if you need it for the JMX work then 
lets consider how this can be optionally done, example, add a service 
endpoint listener and add the classes map from there, etc, so lets 
remove those lines for now

Thanks, Sergey

On 01/04/14 07:43, ffang@apache.org wrote:
> Repository: cxf
> Updated Branches:
>    refs/heads/master ee7ade9e4 -> 99eb3de3a
>
>
> [CXF-5661]add more JMX operations for ManagedEndpoint mbean
>
>
> Project: http://git-wip-us.apache.org/repos/asf/cxf/repo
> Commit: http://git-wip-us.apache.org/repos/asf/cxf/commit/99eb3de3
> Tree: http://git-wip-us.apache.org/repos/asf/cxf/tree/99eb3de3
> Diff: http://git-wip-us.apache.org/repos/asf/cxf/diff/99eb3de3
>
> Branch: refs/heads/master
> Commit: 99eb3de3ab81776442f0fb1893f84c33a6b65242
> Parents: ee7ade9
> Author: Freeman Fang <fr...@gmail.com>
> Authored: Tue Apr 1 14:42:49 2014 +0800
> Committer: Freeman Fang <fr...@gmail.com>
> Committed: Tue Apr 1 14:42:49 2014 +0800
>
> ----------------------------------------------------------------------
>   core/pom.xml                                    |  33 +-
>   .../BeanValidationAnnotationIntrospector.java   | 110 ++++
>   .../BeanValidationAnnotationModule.java         |  40 ++
>   .../cxf/endpoint/FourSpacePrettyPrinter.java    |  78 +++
>   ...IgnorePropertiesBackedByTransientFields.java | 241 +++++++++
>   .../apache/cxf/endpoint/JsonSchemaLookup.java   |  99 ++++
>   .../apache/cxf/endpoint/ManagedEndpoint.java    | 524 +++++++++++++++++++
>   parent/pom.xml                                  |  22 +-
>   .../cxf/jaxrs/AbstractJAXRSFactoryBean.java     |   8 +-
>   rt/pom.xml                                      |   1 -
>   .../cxf/jaxrs/model/wadl/WadlGenerator.java     |  24 +-
>   .../cxf/jaxrs/swagger/SwaggerFeature.java       |  18 +
>   services/pom.xml                                |   1 -
>   services/xkms/pom.xml                           |   1 -
>   systests/jaxrs/pom.xml                          |  21 +
>   .../systest/jaxrs/RestJsonSchemaJMXTest.java    | 162 ++++++
>   .../org/apache/cxf/systest/jaxrs/jmx-enable.xml |  16 +
>   systests/jaxws/pom.xml                          |  21 +
>   .../cxf/systest/jaxws/JsonSchemaJMXTest.java    | 146 ++++++
>   .../org/apache/cxf/systest/jaxws/jmx-enable.xml |  28 +
>   20 files changed, 1580 insertions(+), 14 deletions(-)
> ----------------------------------------------------------------------
>
>
> http://git-wip-us.apache.org/repos/asf/cxf/blob/99eb3de3/core/pom.xml
> ----------------------------------------------------------------------
> diff --git a/core/pom.xml b/core/pom.xml
> index 199024f..546bcab 100644
> --- a/core/pom.xml
> +++ b/core/pom.xml
> @@ -187,7 +187,7 @@
>           <dependency>
>               <groupId>org.osgi</groupId>
>               <artifactId>org.osgi.compendium</artifactId>
> -            <scope>provided</scope>
> +            <scope>compile</scope>
>           </dependency>
>           <dependency>
>               <groupId>net.java.dev.msv</groupId>
> @@ -201,6 +201,37 @@
>               <optional>true</optional>
>               <scope>provided</scope>
>           </dependency>
> +
> +        <dependency>
> +            <groupId>com.fasterxml.jackson.module</groupId>
> +            <artifactId>jackson-module-jaxb-annotations</artifactId>
> +            <optional>true</optional>
> +        </dependency>
> +
> +        <dependency>
> +            <groupId>com.fasterxml.jackson.core</groupId>
> +            <artifactId>jackson-databind</artifactId>
> +            <optional>true</optional>
> +        </dependency>
> +
> +        <dependency>
> +            <groupId>com.fasterxml.jackson.core</groupId>
> +            <artifactId>jackson-annotations</artifactId>
> +            <optional>true</optional>
> +        </dependency>
> +
> +        <dependency>
> +            <groupId>com.fasterxml.jackson.core</groupId>
> +            <artifactId>jackson-core</artifactId>
> +            <optional>true</optional>
> +        </dependency>
> +
> +        <dependency>
> +            <groupId>javax.validation</groupId>
> +            <artifactId>validation-api</artifactId>
> +            <optional>true</optional>
> +        </dependency>
> +
>       </dependencies>
>       <build>
>           <plugins>
>
> http://git-wip-us.apache.org/repos/asf/cxf/blob/99eb3de3/core/src/main/java/org/apache/cxf/endpoint/BeanValidationAnnotationIntrospector.java
> ----------------------------------------------------------------------
> diff --git a/core/src/main/java/org/apache/cxf/endpoint/BeanValidationAnnotationIntrospector.java b/core/src/main/java/org/apache/cxf/endpoint/BeanValidationAnnotationIntrospector.java
> new file mode 100644
> index 0000000..936c039
> --- /dev/null
> +++ b/core/src/main/java/org/apache/cxf/endpoint/BeanValidationAnnotationIntrospector.java
> @@ -0,0 +1,110 @@
> +/**
> + * Licensed to the Apache Software Foundation (ASF) under one
> + * or more contributor license agreements. See the NOTICE file
> + * distributed with this work for additional information
> + * regarding copyright ownership. The ASF licenses this file
> + * to you under the Apache License, Version 2.0 (the
> + * "License"); you may not use this file except in compliance
> + * with the License. You may obtain a copy of the License at
> + *
> + * http://www.apache.org/licenses/LICENSE-2.0
> + *
> + * Unless required by applicable law or agreed to in writing,
> + * software distributed under the License is distributed on an
> + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
> + * KIND, either express or implied. See the License for the
> + * specific language governing permissions and limitations
> + * under the License.
> + */
> +package org.apache.cxf.endpoint;
> +
> +
> +import java.beans.Introspector;
> +import java.lang.reflect.Field;
> +import java.lang.reflect.Member;
> +import java.lang.reflect.Modifier;
> +import java.util.logging.Level;
> +import java.util.logging.Logger;
> +
> +import javax.validation.constraints.NotNull;
> +
> +import com.fasterxml.jackson.core.Version;
> +import com.fasterxml.jackson.databind.AnnotationIntrospector;
> +import com.fasterxml.jackson.databind.introspect.AnnotatedMember;
> +import com.fasterxml.jackson.databind.introspect.AnnotatedMethod;
> +import com.fasterxml.jackson.databind.type.TypeFactory;
> +
> +import org.apache.cxf.common.logging.LogUtils;
> +
> +
> +public class BeanValidationAnnotationIntrospector extends AnnotationIntrospector {
> +    private static final transient Logger LOG = LogUtils.getL7dLogger(BeanValidationAnnotationIntrospector.class);
> +
> +    protected final TypeFactory typeFactory;
> +
> +    public BeanValidationAnnotationIntrospector(TypeFactory typeFactory) {
> +        this.typeFactory = (typeFactory == null) ? TypeFactory.defaultInstance() : typeFactory;
> +    }
> +
> +
> +    @Override
> +    public Version version() {
> +        return new Version(1, 1, 0, "", "cxf", "json-schema-mbean");
> +    }
> +
> +
> +    @Override
> +    public boolean hasIgnoreMarker(AnnotatedMember m) {
> +        Member member = m.getMember();
> +        int modifiers = member.getModifiers();
> +        if (Modifier.isTransient(modifiers)) {
> +            if (LOG.isLoggable(Level.FINE)) {
> +                LOG.fine("Ignoring transient member " + m);
> +            }
> +            return true;
> +        } else if (m instanceof AnnotatedMethod) {
> +            AnnotatedMethod method = (AnnotatedMethod) m;
> +            String methodName = method.getName();
> +            // lets see if there is a transient field of the same name as the getter
> +            if (methodName.startsWith("get") && method.getParameterCount() == 0) {
> +                String fieldName = Introspector.decapitalize(methodName.substring(3));
> +                Class<?> declaringClass = method.getDeclaringClass();
> +                Field field = findField(fieldName, declaringClass);
> +                if (field != null) {
> +                    int fieldModifiers = field.getModifiers();
> +                    if (Modifier.isTransient(fieldModifiers)) {
> +                        LOG.fine("Ignoring member " + m + " due to transient field called " + fieldName);
> +                        return true;
> +                    }
> +                }
> +            }
> +        }
> +        return super.hasIgnoreMarker(m);
> +
> +    }
> +
> +    protected static Field findField(String fieldName, Class<?> declaringClass) {
> +        try {
> +            return declaringClass.getDeclaredField(fieldName);
> +        } catch (NoSuchFieldException e) {
> +            Class<?> superclass = declaringClass.getSuperclass();
> +            if (superclass != null && superclass != declaringClass) {
> +                return findField(fieldName, superclass);
> +            } else {
> +                return null;
> +            }
> +        }
> +    }
> +
> +    @Override
> +    public Boolean hasRequiredMarker(AnnotatedMember m) {
> +        NotNull annotation = m.getAnnotation(NotNull.class);
> +        if (annotation == null) {
> +            return null;
> +        }
> +        return Boolean.TRUE;
> +    }
> +
> +
> +}
> +
>
> http://git-wip-us.apache.org/repos/asf/cxf/blob/99eb3de3/core/src/main/java/org/apache/cxf/endpoint/BeanValidationAnnotationModule.java
> ----------------------------------------------------------------------
> diff --git a/core/src/main/java/org/apache/cxf/endpoint/BeanValidationAnnotationModule.java b/core/src/main/java/org/apache/cxf/endpoint/BeanValidationAnnotationModule.java
> new file mode 100644
> index 0000000..f737178
> --- /dev/null
> +++ b/core/src/main/java/org/apache/cxf/endpoint/BeanValidationAnnotationModule.java
> @@ -0,0 +1,40 @@
> +/**
> + * Licensed to the Apache Software Foundation (ASF) under one
> + * or more contributor license agreements. See the NOTICE file
> + * distributed with this work for additional information
> + * regarding copyright ownership. The ASF licenses this file
> + * to you under the Apache License, Version 2.0 (the
> + * "License"); you may not use this file except in compliance
> + * with the License. You may obtain a copy of the License at
> + *
> + * http://www.apache.org/licenses/LICENSE-2.0
> + *
> + * Unless required by applicable law or agreed to in writing,
> + * software distributed under the License is distributed on an
> + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
> + * KIND, either express or implied. See the License for the
> + * specific language governing permissions and limitations
> + * under the License.
> + */
> +package org.apache.cxf.endpoint;
> +
> +
> +
> +import com.fasterxml.jackson.databind.module.SimpleModule;
> +
> +
> +public class BeanValidationAnnotationModule extends SimpleModule {
> +
> +    public BeanValidationAnnotationModule() {
> +        super("bean-validation-annotations");
> +    }
> +
> +    @Override
> +    public void setupModule(SetupContext context) {
> +        BeanValidationAnnotationIntrospector introspector =
> +            new BeanValidationAnnotationIntrospector(context.getTypeFactory());
> +
> +        context.insertAnnotationIntrospector(introspector);
> +    }
> +
> +}
>
> http://git-wip-us.apache.org/repos/asf/cxf/blob/99eb3de3/core/src/main/java/org/apache/cxf/endpoint/FourSpacePrettyPrinter.java
> ----------------------------------------------------------------------
> diff --git a/core/src/main/java/org/apache/cxf/endpoint/FourSpacePrettyPrinter.java b/core/src/main/java/org/apache/cxf/endpoint/FourSpacePrettyPrinter.java
> new file mode 100644
> index 0000000..e8dc6d8
> --- /dev/null
> +++ b/core/src/main/java/org/apache/cxf/endpoint/FourSpacePrettyPrinter.java
> @@ -0,0 +1,78 @@
> +/**
> + * Licensed to the Apache Software Foundation (ASF) under one
> + * or more contributor license agreements. See the NOTICE file
> + * distributed with this work for additional information
> + * regarding copyright ownership. The ASF licenses this file
> + * to you under the Apache License, Version 2.0 (the
> + * "License"); you may not use this file except in compliance
> + * with the License. You may obtain a copy of the License at
> + *
> + * http://www.apache.org/licenses/LICENSE-2.0
> + *
> + * Unless required by applicable law or agreed to in writing,
> + * software distributed under the License is distributed on an
> + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
> + * KIND, either express or implied. See the License for the
> + * specific language governing permissions and limitations
> + * under the License.
> + */
> +package org.apache.cxf.endpoint;
> +
> +import java.io.IOException;
> +import java.util.Arrays;
> +
> +import com.fasterxml.jackson.core.JsonGenerationException;
> +import com.fasterxml.jackson.core.JsonGenerator;
> +import com.fasterxml.jackson.core.util.DefaultPrettyPrinter;
> +
> +public class FourSpacePrettyPrinter extends DefaultPrettyPrinter {
> +
> +    public FourSpacePrettyPrinter() {
> +        _objectIndenter = Lf4SpacesIndenter.INSTANCE;
> +    }
> +
> +    public static class Lf4SpacesIndenter extends NopIndenter {
> +        public static final Lf4SpacesIndenter INSTANCE = new Lf4SpacesIndenter();
> +
> +        private static final String SYS_LF;
> +
> +        private static int spacecount = 64;
> +        private static char[] spaces = new char[spacecount];
> +
> +        static {
> +            String lf = null;
> +            try {
> +                lf = System.getProperty("line.separator");
> +            } catch (Throwable t) {
> +                //
> +            }
> +            SYS_LF = (lf == null) ? "\n" : lf;
> +        }
> +
> +
> +        static {
> +            Arrays.fill(spaces, ' ');
> +        }
> +
> +
> +
> +        @Override
> +        public boolean isInline() {
> +            return false;
> +        }
> +
> +        @Override
> +        public void writeIndentation(JsonGenerator jg, int level) throws IOException, JsonGenerationException {
> +            jg.writeRaw(SYS_LF);
> +            if (level > 0) { // should we err on negative values (as there's some flaw?)
> +                level = level * 4; // 4 spaces per level
> +                while (level > spacecount) { // should never happen but...
> +                    jg.writeRaw(spaces, 0, spacecount);
> +                    level -= spaces.length;
> +                }
> +                jg.writeRaw(spaces, 0, level);
> +            }
> +        }
> +    }
> +
> +}
>
> http://git-wip-us.apache.org/repos/asf/cxf/blob/99eb3de3/core/src/main/java/org/apache/cxf/endpoint/IgnorePropertiesBackedByTransientFields.java
> ----------------------------------------------------------------------
> diff --git a/core/src/main/java/org/apache/cxf/endpoint/IgnorePropertiesBackedByTransientFields.java b/core/src/main/java/org/apache/cxf/endpoint/IgnorePropertiesBackedByTransientFields.java
> new file mode 100644
> index 0000000..278cc37
> --- /dev/null
> +++ b/core/src/main/java/org/apache/cxf/endpoint/IgnorePropertiesBackedByTransientFields.java
> @@ -0,0 +1,241 @@
> +/**
> + * Licensed to the Apache Software Foundation (ASF) under one
> + * or more contributor license agreements. See the NOTICE file
> + * distributed with this work for additional information
> + * regarding copyright ownership. The ASF licenses this file
> + * to you under the Apache License, Version 2.0 (the
> + * "License"); you may not use this file except in compliance
> + * with the License. You may obtain a copy of the License at
> + *
> + * http://www.apache.org/licenses/LICENSE-2.0
> + *
> + * Unless required by applicable law or agreed to in writing,
> + * software distributed under the License is distributed on an
> + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
> + * KIND, either express or implied. See the License for the
> + * specific language governing permissions and limitations
> + * under the License.
> + */
> +package org.apache.cxf.endpoint;
> +
> +
> +
> +import java.beans.Introspector;
> +import java.lang.reflect.Field;
> +import java.lang.reflect.Member;
> +import java.lang.reflect.Method;
> +import java.lang.reflect.Modifier;
> +import java.util.logging.Level;
> +import java.util.logging.Logger;
> +
> +import com.fasterxml.jackson.annotation.JsonAutoDetect;
> +import com.fasterxml.jackson.annotation.PropertyAccessor;
> +import com.fasterxml.jackson.databind.introspect.AnnotatedField;
> +import com.fasterxml.jackson.databind.introspect.AnnotatedMember;
> +import com.fasterxml.jackson.databind.introspect.AnnotatedMethod;
> +import com.fasterxml.jackson.databind.introspect.VisibilityChecker;
> +
> +import org.apache.cxf.common.logging.LogUtils;
> +
> +public class IgnorePropertiesBackedByTransientFields implements
> +    VisibilityChecker<IgnorePropertiesBackedByTransientFields> {
> +
> +    private static final transient Logger LOG = LogUtils.getL7dLogger(IgnorePropertiesBackedByTransientFields.class);
> +    private final VisibilityChecker<?> defaultChecker;
> +
> +    public IgnorePropertiesBackedByTransientFields(VisibilityChecker<?> defaultChecker) {
> +        this.defaultChecker = defaultChecker;
> +    }
> +
> +    @Override
> +    public boolean isGetterVisible(AnnotatedMethod method) {
> +        boolean answer = defaultChecker.isGetterVisible(method);
> +        if (answer) {
> +            answer = isGetterMethodWithFieldVisible(method, getGetterFieldName(
> +                     method.getName()), method.getDeclaringClass())
> +                     && isGetterMethodRetItselfVisible(method.getMember(), method.getDeclaringClass());
> +        }
> +        return answer;
> +    }
> +
> +    @Override
> +    public boolean isGetterVisible(Method method) {
> +        boolean answer = defaultChecker.isGetterVisible(method);
> +        if (answer) {
> +            answer = isGetterMethodWithFieldVisible(method, getGetterFieldName(
> +                     method.getName()), method.getDeclaringClass())
> +                     && isGetterMethodRetItselfVisible(method, method.getDeclaringClass());
> +        }
> +        return answer;
> +    }
> +
> +    @Override
> +    public boolean isIsGetterVisible(AnnotatedMethod method) {
> +        boolean answer = defaultChecker.isIsGetterVisible(method);
> +        if (answer) {
> +            answer = isGetterMethodWithFieldVisible(method, getIsGetterFieldName(
> +                     method.getName()), method.getDeclaringClass())
> +                     && isGetterMethodRetItselfVisible(method.getMember(), method.getDeclaringClass());
> +        }
> +        return answer;
> +    }
> +
> +    @Override
> +    public boolean isIsGetterVisible(Method method) {
> +        boolean answer = defaultChecker.isIsGetterVisible(method);
> +        if (answer) {
> +            answer = isGetterMethodWithFieldVisible(method, getIsGetterFieldName(
> +                     method.getName()), method.getDeclaringClass())
> +                     && isGetterMethodRetItselfVisible(method, method.getDeclaringClass());
> +        }
> +        return answer;
> +    }
> +
> +    protected String getIsGetterFieldName(String methodName) {
> +        return Introspector.decapitalize(methodName.substring(2));
> +    }
> +    protected String getGetterFieldName(String methodName) {
> +        return Introspector.decapitalize(methodName.substring(3));
> +    }
> +
> +    /**
> +     * Returns false if the getter method has a field of the same name which is transient
> +     * @return
> +     */
> +    protected boolean isGetterMethodWithFieldVisible(Object method,
> +                                                     String fieldName,
> +                                                     Class<?> declaringClass) {
> +        Field field = findField(fieldName, declaringClass);
> +        if (field != null) {
> +            int fieldModifiers = field.getModifiers();
> +            if (Modifier.isTransient(fieldModifiers)) {
> +                if (LOG.isLoggable(Level.FINE)) {
> +                    LOG.fine("Ignoring getter " + method + " due to transient field called "
> +                        + fieldName);
> +                }
> +                return false;
> +            }
> +        }
> +        return true;
> +    }
> +
> +
> +    /**
> +     * Returns false if the getter method just return the declaringClass itself to avoid the
> +     * recusive dead loop
> +     * @return
> +     */
> +    protected boolean isGetterMethodRetItselfVisible(Method method,
> +                                                     Class<?> declaringClass) {
> +        if (method != null && method.getReturnType().getName().equals(declaringClass.getName())) {
> +            if (LOG.isLoggable(Level.FINE)) {
> +                LOG.fine("Ignoring getter " + method + " due to return same type as declaringClass itself");
> +            }
> +            return false;
> +        }
> +        return true;
> +    }
> +
> +
> +    // Delegated methods
> +    //-------------------------------------------------------------------------
> +
> +    @Override
> +    public boolean isCreatorVisible(AnnotatedMember m) {
> +        return defaultChecker.isCreatorVisible(m);
> +    }
> +
> +    @Override
> +    public boolean isCreatorVisible(Member m) {
> +        return defaultChecker.isCreatorVisible(m);
> +    }
> +
> +    @Override
> +    public boolean isFieldVisible(AnnotatedField f) {
> +        return defaultChecker.isFieldVisible(f);
> +    }
> +
> +    @Override
> +    public boolean isFieldVisible(Field f) {
> +        return defaultChecker.isFieldVisible(f);
> +    }
> +    @Override
> +    public boolean isSetterVisible(AnnotatedMethod m) {
> +        return defaultChecker.isSetterVisible(m);
> +    }
> +
> +    @Override
> +    public boolean isSetterVisible(Method m) {
> +        return defaultChecker.isSetterVisible(m);
> +    }
> +
> +    @Override
> +    public IgnorePropertiesBackedByTransientFields with(JsonAutoDetect ann) {
> +        return castToPropertiesBackedByTransientFields(defaultChecker.with(ann));
> +    }
> +
> +    @Override
> +    public IgnorePropertiesBackedByTransientFields with(JsonAutoDetect.Visibility v) {
> +        return castToPropertiesBackedByTransientFields(defaultChecker.with(v));
> +    }
> +
> +    @Override
> +    public IgnorePropertiesBackedByTransientFields withCreatorVisibility(JsonAutoDetect.Visibility v) {
> +        return castToPropertiesBackedByTransientFields(defaultChecker.withCreatorVisibility(v));
> +    }
> +
> +    @Override
> +    public IgnorePropertiesBackedByTransientFields withFieldVisibility(JsonAutoDetect.Visibility v) {
> +        return castToPropertiesBackedByTransientFields(defaultChecker.withFieldVisibility(v));
> +    }
> +
> +    @Override
> +    public IgnorePropertiesBackedByTransientFields withGetterVisibility(JsonAutoDetect.Visibility v) {
> +        return castToPropertiesBackedByTransientFields(defaultChecker.withGetterVisibility(v));
> +    }
> +
> +    @Override
> +    public IgnorePropertiesBackedByTransientFields withIsGetterVisibility(JsonAutoDetect.Visibility v) {
> +        return castToPropertiesBackedByTransientFields(defaultChecker.withIsGetterVisibility(v));
> +    }
> +
> +    @Override
> +    public IgnorePropertiesBackedByTransientFields withSetterVisibility(JsonAutoDetect.Visibility v) {
> +        return castToPropertiesBackedByTransientFields(defaultChecker.withSetterVisibility(v));
> +    }
> +
> +    @Override
> +    public IgnorePropertiesBackedByTransientFields withVisibility(PropertyAccessor method,
> +                                                                  JsonAutoDetect.Visibility v) {
> +        return castToPropertiesBackedByTransientFields(defaultChecker.withVisibility(method, v));
> +    }
> +
> +
> +    protected IgnorePropertiesBackedByTransientFields castToPropertiesBackedByTransientFields(Object value) {
> +        if (value instanceof IgnorePropertiesBackedByTransientFields) {
> +            return (IgnorePropertiesBackedByTransientFields) value;
> +        } else {
> +            if (value != null) {
> +                if (value instanceof VisibilityChecker<?>) {
> +                    return new IgnorePropertiesBackedByTransientFields((VisibilityChecker<?>) value);
> +                }
> +                LOG.warning("Could not convert value to "
> +                            + "IgnorePropertiesBackedByTransientFields as was "
> +                            + value.getClass().getName() + " " + value);
> +            }
> +            return null;
> +        }
> +    }
> +    protected static Field findField(String fieldName, Class<?> declaringClass) {
> +        try {
> +            return declaringClass.getDeclaredField(fieldName);
> +        } catch (NoSuchFieldException e) {
> +            Class<?> superclass = declaringClass.getSuperclass();
> +            if (superclass != null && superclass != declaringClass) {
> +                return findField(fieldName, superclass);
> +            } else {
> +                return null;
> +            }
> +        }
> +    }
> +}
>
> http://git-wip-us.apache.org/repos/asf/cxf/blob/99eb3de3/core/src/main/java/org/apache/cxf/endpoint/JsonSchemaLookup.java
> ----------------------------------------------------------------------
> diff --git a/core/src/main/java/org/apache/cxf/endpoint/JsonSchemaLookup.java b/core/src/main/java/org/apache/cxf/endpoint/JsonSchemaLookup.java
> new file mode 100644
> index 0000000..8316b24
> --- /dev/null
> +++ b/core/src/main/java/org/apache/cxf/endpoint/JsonSchemaLookup.java
> @@ -0,0 +1,99 @@
> +/**
> + * Licensed to the Apache Software Foundation (ASF) under one
> + * or more contributor license agreements. See the NOTICE file
> + * distributed with this work for additional information
> + * regarding copyright ownership. The ASF licenses this file
> + * to you under the Apache License, Version 2.0 (the
> + * "License"); you may not use this file except in compliance
> + * with the License. You may obtain a copy of the License at
> + *
> + * http://www.apache.org/licenses/LICENSE-2.0
> + *
> + * Unless required by applicable law or agreed to in writing,
> + * software distributed under the License is distributed on an
> + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
> + * KIND, either express or implied. See the License for the
> + * specific language governing permissions and limitations
> + * under the License.
> + */
> +package org.apache.cxf.endpoint;
> +
> +
> +import java.util.logging.Level;
> +import java.util.logging.Logger;
> +
> +import com.fasterxml.jackson.databind.ObjectMapper;
> +import com.fasterxml.jackson.databind.ObjectWriter;
> +import com.fasterxml.jackson.module.jaxb.JaxbAnnotationModule;
> +
> +import org.apache.cxf.common.logging.LogUtils;
> +
> +
> +
> +public class JsonSchemaLookup {
> +
> +    private static final Logger LOG = LogUtils.getL7dLogger(JsonSchemaLookup.class);
> +
> +    private static JsonSchemaLookup singleton;
> +
> +    private ObjectMapper mapper;
> +
> +    public JsonSchemaLookup() {
> +    }
> +
> +    public static JsonSchemaLookup getSingleton() {
> +        if (singleton == null) {
> +            // lazy create one
> +            new JsonSchemaLookup().init();
> +        }
> +        return singleton;
> +    }
> +
> +    public void init() {
> +        LOG.log(Level.INFO, "Creating JsonSchemaLookup instance");
> +        try {
> +            if (mapper == null) {
> +                mapper = new ObjectMapper();
> +
> +                mapper.setVisibilityChecker(new IgnorePropertiesBackedByTransientFields(mapper.getVisibilityChecker()));
> +
> +                JaxbAnnotationModule module1 = new JaxbAnnotationModule();
> +                mapper.registerModule(module1);
> +
> +                BeanValidationAnnotationModule module2 = new BeanValidationAnnotationModule();
> +                mapper.registerModule(module2);
> +
> +            }
> +            // now lets expose the mbean...
> +            singleton = this;
> +        } catch (Exception e) {
> +            LOG.log(Level.WARNING, "Exception during initialization: ", e);
> +            throw new RuntimeException(e);
> +        }
> +    }
> +
> +
> +
> +
> +
> +
> +    public String getSchemaForClass(Class<?> clazz) {
> +        LOG.info("Looking up schema for " + clazz.getCanonicalName());
> +        String name = clazz.getName();
> +        try {
> +            ObjectWriter writer = mapper.writer().with(new FourSpacePrettyPrinter());
> +            return writer.writeValueAsString(mapper.generateJsonSchema(clazz));
> +        } catch (Exception e) {
> +            LOG.log(Level.FINEST, "Failed to generate JSON schema for class " + name, e);
> +            return "";
> +        }
> +    }
> +
> +    public ObjectMapper getMapper() {
> +        return mapper;
> +    }
> +
> +    public void setMapper(ObjectMapper mapper) {
> +        this.mapper = mapper;
> +    }
> +}
>
> http://git-wip-us.apache.org/repos/asf/cxf/blob/99eb3de3/core/src/main/java/org/apache/cxf/endpoint/ManagedEndpoint.java
> ----------------------------------------------------------------------
> diff --git a/core/src/main/java/org/apache/cxf/endpoint/ManagedEndpoint.java b/core/src/main/java/org/apache/cxf/endpoint/ManagedEndpoint.java
> index de53e8b..380af6d 100644
> --- a/core/src/main/java/org/apache/cxf/endpoint/ManagedEndpoint.java
> +++ b/core/src/main/java/org/apache/cxf/endpoint/ManagedEndpoint.java
> @@ -19,16 +19,43 @@
>
>   package org.apache.cxf.endpoint;
>
> +import java.io.BufferedReader;
> +import java.io.IOException;
> +import java.io.StringReader;
> +import java.io.StringWriter;
> +import java.util.Dictionary;
> +import java.util.HashSet;
> +import java.util.List;
> +import java.util.Set;
> +import java.util.logging.Level;
> +import java.util.logging.Logger;
> +
>   import javax.management.JMException;
>   import javax.management.ObjectName;
> +import javax.xml.bind.JAXBContext;
> +import javax.xml.bind.Marshaller;
> +
> +import com.fasterxml.jackson.databind.ObjectMapper;
>
>   import org.apache.cxf.Bus;
> +import org.apache.cxf.common.logging.LogUtils;
> +import org.apache.cxf.common.util.PackageUtils;
>   import org.apache.cxf.common.util.StringUtils;
> +import org.apache.cxf.feature.Feature;
>   import org.apache.cxf.management.ManagedComponent;
>   import org.apache.cxf.management.ManagementConstants;
>   import org.apache.cxf.management.annotation.ManagedAttribute;
>   import org.apache.cxf.management.annotation.ManagedOperation;
>   import org.apache.cxf.management.annotation.ManagedResource;
> +import org.apache.cxf.service.model.BindingInfo;
> +import org.apache.cxf.service.model.BindingOperationInfo;
> +import org.apache.cxf.service.model.MessagePartInfo;
> +import org.apache.cxf.service.model.ServiceInfo;
> +import org.osgi.framework.BundleContext;
> +import org.osgi.framework.FrameworkUtil;
> +import org.osgi.framework.ServiceReference;
> +import org.osgi.service.cm.Configuration;
> +import org.osgi.service.cm.ConfigurationAdmin;
>
>   @ManagedResource(componentName = "Endpoint",
>                    description = "Responsible for managing server instances.")
> @@ -36,6 +63,10 @@ import org.apache.cxf.management.annotation.ManagedResource;
>   public class ManagedEndpoint implements ManagedComponent, ServerLifeCycleListener {
>       public static final String ENDPOINT_NAME = "managed.endpoint.name";
>       public static final String SERVICE_NAME = "managed.service.name";
> +    public static final String INDENTION = "    ";
> +    private static final Logger LOG = LogUtils.getL7dLogger(ManagedEndpoint.class);
> +
> +    private final String eol = System.getProperty("line.separator");
>
>       private Bus bus;
>       private Endpoint endpoint;
> @@ -43,6 +74,8 @@ public class ManagedEndpoint implements ManagedComponent, ServerLifeCycleListene
>       private enum State { CREATED, STARTED, STOPPED };
>       private State state = State.CREATED;
>
> +    private ConfigurationAdmin configurationAdmin;
> +
>       public ManagedEndpoint(Bus b, Endpoint ep, Server s) {
>           bus = b;
>           endpoint = ep;
> @@ -85,6 +118,497 @@ public class ManagedEndpoint implements ManagedComponent, ServerLifeCycleListene
>       public String getState() {
>           return state.toString();
>       }
> +
> +    @ManagedAttribute(description = "The cxf servlet context", currencyTimeLimit = 60)
> +    public String getServletContext() {
> +        if (!isInOSGi()) {
> +            LOG.log(Level.FINE, "Not In OSGi.");
> +            return null; //not in OSGi container
> +        }
> +        String ret = "/cxf"; //if can't get it from configAdmin use the default value
> +        if (getConfigurationAdmin() != null) {
> +            try {
> +                Configuration configuration = getConfigurationAdmin().getConfiguration("org.apache.cxf.osgi");
> +                if (configuration != null) {
> +                    Dictionary properties = configuration.getProperties();
> +                    if (properties != null) {
> +                        String servletContext = (String)configuration.getProperties().
> +                            get("org.apache.cxf.servlet.context");
> +                        if (servletContext != null) {
> +                            ret = servletContext;
> +                        }
> +                    }
> +                }
> +            } catch (Exception e) {
> +                LOG.log(Level.WARNING, "getServletContext failed.", e);
> +            }
> +        }
> +        return ret;
> +    }
> +
> +    @ManagedAttribute(description = "if the endpoint has swagger doc or not", currencyTimeLimit = 60)
> +    public boolean isSwagger() {
> +        if (!isWADL()) {
> +            return false;
> +        }
> +        List<Feature> features = server.getEndpoint().getActiveFeatures();
> +        if (features != null) {
> +            for (Feature feature : features) {
> +                if (feature.getClass().getName().endsWith("SwaggerFeature")) {
> +                    return true;
> +                }
> +            }
> +        }
> +        return false;
> +    }
> +
> +    @ManagedAttribute(description = "if the endpoint has wsdl doc or not", currencyTimeLimit = 60)
> +    public boolean isWSDL() {
> +        return !isWADL();
> +    }
> +
> +    @ManagedAttribute(description = "if the endpoint has WADL doc or not", currencyTimeLimit = 60)
> +    public boolean isWADL() {
> +        if (endpoint.getEndpointInfo().getBinding().
> +            getBindingId().equals("http://apache.org/cxf/binding/jaxrs")) {
> +            return true;
> +        }
> +        return false;
> +    }
> +
> +    @ManagedOperation(description = "get the JSON schema from a given endpoint", currencyTimeLimit = 60)
> +    public String getJSONSchema() {
> +        String ret = "";
> +        if (!isWSDL()) {
> +            Set<Class<?>> resourceTypes = (Set<Class<?>>)endpoint.get("jaxrs.resource.types");
> +            if (resourceTypes != null) {
> +                try {
> +                    ret = ret + getBeginIndentionWithReturn(1) + "\""
> +                        + "definitions" + "\" " + " : {"
> +                        + getEol();
> +                    for (Class<?> cls : resourceTypes) {
> +                        if (JsonSchemaLookup.getSingleton()
> +                            .getSchemaForClass(cls).length() > 0) {
> +                            ret = ret + getIndention(2) + "\"" + cls.getName() + "\" : "
> +                                + getEol();
> +
> +                            ret = ret
> +                                + rollbackEol(reformatIndent(JsonSchemaLookup.getSingleton()
> +                                                 .getSchemaForClass(cls), 3)) + "," + getEol();
> +                        }
> +
> +                    }
> +                    ret = rollbackColon(rollbackEol(ret)) + getEndIndentionWithReturn(1);
> +                    ret = ret + getEndIndentionWithReturn(0);
> +                } catch (Throwable e) {
> +                    LOG.log(Level.WARNING, "getJSONSchema failed.", e);
> +                }
> +            }
> +        } else {
> +            try {
> +                for (ServiceInfo serviceInfo : endpoint.getService().getServiceInfos()) {
> +                    for (BindingInfo bindingInfo : serviceInfo.getBindings()) {
> +                        ret = ret + getBeginIndentionWithReturn(1) + "\"operations\" : "
> +                            + getBeginIndentionWithReturn(0);
> +                        for (BindingOperationInfo boi : bindingInfo.getOperations()) {
> +                            ret = ret  + getIndention(2) + "\""
> +                                  + boi.getOperationInfo().getName().getLocalPart() + "\" " + " : "
> +                                  + getBeginIndentionWithReturn(3);
> +                            if (boi.getInput() != null && boi.getInput().getMessageParts() != null) {
> +                                ret = ret + "\"input\" : " + getBeginIndentionWithReturn(4) + "\"type\" : \""
> +                                      + boi.getOperationInfo().getInput().getName().getLocalPart() + "\""
> +                                      + getEndIndentionWithReturn(3) + "," + getEol();
> +
> +                            }
> +                            if (boi.getOutput() != null && boi.getOutput().getMessageParts() != null) {
> +                                ret = ret + getIndention(3) + "\"output\" : "
> +                                      + getBeginIndentionWithReturn(4) + "\"type\" : \""
> +                                      + boi.getOperationInfo().getOutput().getName().getLocalPart() + "\""
> +                                      + getEndIndentionWithReturn(3);
> +                            }
> +                            ret = rollbackColon(rollbackEol(ret)) + getEndIndentionWithReturn(2) + "," + getEol();
> +                        }
> +                        if (ret.length() > 0) {
> +                            ret = rollbackColon(rollbackEol(ret)) + getEndIndentionWithReturn(1) + ",";
> +                        }
> +                        Set<String> addedType = new HashSet<String>();
> +
> +                        ret = ret + getEol() + getIndention(1) + "\"definitions\" : "
> +                            + getBeginIndentionWithReturn(0);
> +                        for (BindingOperationInfo boi : bindingInfo.getOperations()) {
> +
> +                            if (boi.getInput() != null && boi.getInput().getMessageParts() != null
> +                                && !addedType.contains(boi.getOperationInfo().getInput().getName().getLocalPart())) {
> +
> +                                ret = ret + getIndention(2) + "\""
> +                                      + boi.getOperationInfo().getInput().getName().getLocalPart() + "\" : "
> +                                      + getBeginIndentionWithReturnForList(0);
> +                                for (MessagePartInfo mpi : boi.getInput().getMessageParts()) {
> +                                    Class<?> partClass = mpi.getTypeClass();
> +                                    if (partClass != null) {
> +                                        ret = ret
> +                                              + rollbackEol(reformatIndent(JsonSchemaLookup.getSingleton()
> +                                                  .getSchemaForClass(partClass), 3)) + "," + getEol();
> +                                    }
> +                                }
> +                                ret = rollbackColon(rollbackEol(ret)) + getEndIndentionWithReturnForList(2)
> +                                      + "," + getEol();
> +                                addedType.add(boi.getOperationInfo().getInput().getName().getLocalPart());
> +
> +                            }
> +                            if (boi.getOutput() != null && boi.getOutput().getMessageParts() != null
> +                                && !addedType.contains(boi.getOperationInfo().getOutput().getName().getLocalPart())) {
> +
> +                                ret = ret + getIndention(2) + "\""
> +                                      + boi.getOperationInfo().getOutput().getName().getLocalPart()
> +                                      + "\" : " + getBeginIndentionWithReturnForList(0);
> +
> +                                for (MessagePartInfo mpi : boi.getOutput().getMessageParts()) {
> +                                    Class<?> partClass = mpi.getTypeClass();
> +                                    if (partClass != null) {
> +                                        ret = ret
> +                                              + rollbackEol(reformatIndent(JsonSchemaLookup.getSingleton()
> +                                                  .getSchemaForClass(partClass), 3)) + "," + getEol();
> +                                    }
> +                                }
> +                                ret = rollbackColon(rollbackEol(ret)) + getEndIndentionWithReturnForList(2)
> +                                      + "," + getEol();
> +                                addedType.add(boi.getOperationInfo().getOutput().getName().getLocalPart());
> +
> +                            }
> +                        }
> +                        if (ret.length() > 0) {
> +                            ret = rollbackColon(rollbackEol(ret)) + getEndIndentionWithReturn(1);
> +                        }
> +
> +                        if (ret.length() > 0) {
> +                            ret = rollbackColon(ret) + getEndIndentionWithReturn(0);
> +                        }
> +                    }
> +                }
> +
> +            } catch (Throwable e) {
> +                LOG.log(Level.WARNING, "getJSONSchema failed.", e);
> +            }
> +        }
> +        return ret;
> +    }
> +
> +    @ManagedOperation(description = "get the JSON schema from a given class", currencyTimeLimit = 60)
> +    public String getJSONSchemaForClass(String clsName) {
> +        String ret = "";
> +        if (!isWSDL()) {
> +            Set<Class<?>> resourceTypes = (Set<Class<?>>)endpoint.get("jaxrs.resource.types");
> +            if (resourceTypes != null) {
> +                try {
> +                    ret = ret + getBeginIndentionWithReturn(1) + "\""
> +                        + "definitions" + "\" " + " : {"
> +                        + getEol();
> +                    for (Class<?> cls : resourceTypes) {
> +                        if (cls.getName().endsWith(clsName)
> +                            && JsonSchemaLookup.getSingleton().getSchemaForClass(cls).length() > 0) {
> +                            ret = ret + getIndention(2) + "\"" + cls.getName() + "\" : "
> +                                  + getEol();
> +
> +                            ret = ret
> +                                  + reformatIndent(JsonSchemaLookup.getSingleton().getSchemaForClass(cls), 3);
> +                            ret = ret + getEol();
> +                        }
> +                    }
> +                    ret = ret + getEndIndentionWithReturn(1);
> +                    ret = ret + getEndIndentionWithReturn(0);
> +                } catch (Throwable e) {
> +                    LOG.log(Level.WARNING, "getJSONSchemaForClass failed.", e);
> +                }
> +            }
> +        } else {
> +
> +            for (ServiceInfo serviceInfo : endpoint.getService().getServiceInfos()) {
> +                for (BindingInfo bindingInfo : serviceInfo.getBindings()) {
> +                    ret = ret + getBeginIndentionWithReturn(1) + "\""
> +                        + "definitions" + "\" " + " : {"
> +                        + getEol();
> +                    for (BindingOperationInfo boi : bindingInfo.getOperations()) {
> +
> +                        if (boi.getInput() != null && boi.getInput().getMessageParts() != null) {
> +                            for (MessagePartInfo mpi : boi.getInput().getMessageParts()) {
> +                                Class<?> partClass = mpi.getTypeClass();
> +                                if (partClass != null && partClass.getName().endsWith(clsName)) {
> +                                    ret = ret + getIndention(2) + "\"" + partClass.getName() + "\" : "
> +                                        + getEol();
> +
> +                                    ret = ret
> +                                        + reformatIndent(JsonSchemaLookup.getSingleton()
> +                                                             .getSchemaForClass(partClass), 3);
> +                                }
> +                            }
> +
> +                        }
> +                        if (boi.getOutput() != null && boi.getOutput().getMessageParts() != null) {
> +                            for (MessagePartInfo mpi : boi.getOutput().getMessageParts()) {
> +                                Class<?> partClass = mpi.getTypeClass();
> +                                if (partClass != null && partClass.getName().endsWith(clsName)) {
> +                                    ret = ret + getIndention(2) + "\"" + partClass.getName() + "\" : "
> +                                        + getEol();
> +
> +                                    ret = ret
> +                                        + reformatIndent(JsonSchemaLookup.getSingleton()
> +                                                             .getSchemaForClass(partClass), 3);
> +                                }
> +                            }
> +                        }
> +                    }
> +                    ret = ret + getEndIndentionWithReturn(1);
> +                    ret = ret + getEndIndentionWithReturn(0);
> +                }
> +            }
> +
> +        }
> +        return ret;
> +    }
> +
> +    @ManagedOperation(description = "get the JSON schema from a given soap endpoint for a given operation",
> +                        currencyTimeLimit = 60)
> +    public String getJSONSchemaForOperation(String operationName) {
> +        if (!isWSDL()) {
> +            return null;
> +        }
> +        String ret = "";
> +
> +        for (ServiceInfo serviceInfo : endpoint.getService().getServiceInfos()) {
> +            for (BindingInfo bindingInfo : serviceInfo.getBindings()) {
> +                for (BindingOperationInfo boi : bindingInfo.getOperations()) {
> +                    if (operationName.equals(boi.getOperationInfo().getName().getLocalPart())) {
> +                        ret = ret + getBeginIndentionWithReturn(1) + "\""
> +                              + boi.getOperationInfo().getName().getLocalPart() + "\" " + " : "
> +                              + getBeginIndentionWithReturn(2);
> +                        if (boi.getInput() != null && boi.getInput().getMessageParts() != null) {
> +                            ret = ret + "\"input\" : " + getBeginIndentionWithReturn(4) + "\"type\" : \""
> +                                  + boi.getOperationInfo().getInput().getName().getLocalPart() + "\""
> +                                  + getEndIndentionWithReturn(2) + "," + getEol();
> +
> +                        }
> +                        if (boi.getOutput() != null && boi.getOutput().getMessageParts() != null) {
> +                            ret = ret + getIndention(2) + "\"output\" : " + getBeginIndentionWithReturn(4)
> +                                  + "\"type\" : \"" + boi.getOperationInfo().getOutput().getName().getLocalPart() + "\""
> +                                  + getEndIndentionWithReturn(2);
> +                        }
> +                        ret = rollbackColon(ret) + getEndIndentionWithReturn(1) + ",";
> +
> +                        ret = ret + getEol() + getIndention(1) + "\"definitions\" : "
> +                              + getBeginIndentionWithReturn(2);
> +                        if (boi.getInput() != null && boi.getInput().getMessageParts() != null) {
> +                            ret = ret + "\"" + boi.getOperationInfo().getInput().getName().getLocalPart() + "\" : "
> +                                  + getBeginIndentionWithReturnForList(0);
> +                            for (MessagePartInfo mpi : boi.getInput().getMessageParts()) {
> +                                Class<?> partClass = mpi.getTypeClass();
> +                                if (partClass != null) {
> +                                    ret = ret
> +                                          + rollbackEol(reformatIndent(JsonSchemaLookup.getSingleton()
> +                                                               .getSchemaForClass(partClass), 3)) + "," + getEol();
> +                                }
> +                            }
> +                            ret = rollbackColon(rollbackEol(ret)) + getEndIndentionWithReturnForList(2)
> +                                      + "," + getEol();
> +                        }
> +                        if (boi.getOutput() != null && boi.getOutput().getMessageParts() != null) {
> +                            ret = ret + getIndention(2) + "\""
> +                                  + boi.getOperationInfo().getOutput().getName().getLocalPart()
> +                                  + "\" : " + getBeginIndentionWithReturnForList(0);
> +
> +                            for (MessagePartInfo mpi : boi.getOutput().getMessageParts()) {
> +                                Class<?> partClass = mpi.getTypeClass();
> +                                if (partClass != null) {
> +                                    ret = ret
> +                                          + rollbackEol(reformatIndent(JsonSchemaLookup.getSingleton()
> +                                                               .getSchemaForClass(partClass), 3)) + "," + getEol();
> +                                }
> +                            }
> +                            ret = rollbackColon(rollbackEol(ret)) + getEndIndentionWithReturnForList(2) + ",";
> +                        }
> +
> +                    }
> +
> +                }
> +                if (ret.length() > 0) {
> +                    ret = rollbackColon(ret) + getEndIndentionWithReturn(1);
> +                }
> +
> +                if (ret.length() > 0) {
> +                    ret = rollbackColon(ret) + getEndIndentionWithReturn(0);
> +                }
> +            }
> +        }
> +        return ret;
> +    }
> +
> +    @ManagedOperation(description = "get the package name for a given namespace URI", currencyTimeLimit = 60)
> +    public String getPackageNameByNameSpaceURI(String nameSpaceURI) {
> +        return PackageUtils.getPackageNameByNameSpaceURI(nameSpaceURI);
> +    }
> +
> +    @ManagedOperation(description = "get xml payload from json payload", currencyTimeLimit = 60)
> +    public String jsonToXml(String jsonText, String pojoType) {
> +        ObjectMapper objectMapper = new ObjectMapper();
> +        StringWriter sw = new StringWriter();
> +        try {
> +            Object pojo = objectMapper.readValue(jsonText, findClass(pojoType));
> +            JAXBContext jc = JAXBContext.newInstance(findClass(pojoType));
> +            Marshaller marshaller = jc.createMarshaller();
> +            marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
> +            marshaller.marshal(pojo, sw);
> +        } catch (Exception e) {
> +            LOG.log(Level.WARNING, "jsonToXml failed.", e);
> +        }
> +
> +        return sw.toString();
> +    }
> +
> +    private Class<?> findClass(String clsName) {
> +        if (!isWSDL()) {
> +            Set<Class<?>> resourceTypes = (Set<Class<?>>)endpoint.get("jaxrs.resource.types");
> +            if (resourceTypes != null) {
> +                try {
> +
> +                    for (Class<?> cls : resourceTypes) {
> +                        if (cls.getName().endsWith(clsName)) {
> +                            return cls;
> +                        }
> +                    }
> +
> +                } catch (Throwable e) {
> +                    LOG.log(Level.WARNING, "findClass failed.", e);
> +                }
> +            }
> +        } else {
> +
> +            for (ServiceInfo serviceInfo : endpoint.getService().getServiceInfos()) {
> +                for (BindingInfo bindingInfo : serviceInfo.getBindings()) {
> +                    for (BindingOperationInfo boi : bindingInfo.getOperations()) {
> +
> +                        if (boi.getInput() != null && boi.getInput().getMessageParts() != null) {
> +                            for (MessagePartInfo mpi : boi.getInput().getMessageParts()) {
> +                                Class<?> partClass = mpi.getTypeClass();
> +                                if (partClass != null && partClass.getName().endsWith(clsName)) {
> +                                    return partClass;
> +                                }
> +                            }
> +
> +                        }
> +                        if (boi.getOutput() != null && boi.getOutput().getMessageParts() != null) {
> +                            for (MessagePartInfo mpi : boi.getOutput().getMessageParts()) {
> +                                Class<?> partClass = mpi.getTypeClass();
> +                                if (partClass != null && partClass.getName().endsWith(clsName)) {
> +                                    return partClass;
> +                                }
> +                            }
> +                        }
> +                    }
> +                }
> +            }
> +
> +        }
> +        return null;
> +    }
> +
> +    private String reformatIndent(String input, int startIndent) {
> +        String ret = "";
> +        BufferedReader reader = new BufferedReader(new StringReader(input));
> +        try {
> +            String oneLine;
> +            while ((oneLine = reader.readLine()) != null) {
> +                ret = ret + getIndention(startIndent) + oneLine + getEol();
> +            }
> +        } catch (IOException e) {
> +            LOG.log(Level.WARNING, "reformatIndent failed.", e);
> +        }
> +        return ret;
> +    }
> +
> +    private String rollbackEol(String input) {
> +        String ret = input;
> +        if (ret.endsWith(getEol())) {
> +            ret = ret.substring(0, ret.length() - getEol().length());
> +        }
> +        return ret;
> +    }
> +
> +    private String rollbackColon(String input) {
> +        String ret = input;
> +        if (ret.endsWith(",")) {
> +            ret = ret.substring(0, ret.length() - 1);
> +        }
> +        return ret;
> +    }
> +
> +    private boolean isInOSGi() {
> +        if (FrameworkUtil.getBundle(ManagedEndpoint.class) != null) {
> +            return true;
> +        }
> +        return false;
> +
> +    }
> +
> +
> +    private String getBeginIndentionWithReturn(int n) {
> +        return "{" + getEol() + getIndention(n);
> +    }
> +
> +    private String getEndIndentionWithReturn(int n) {
> +        return getEol() + getIndention(n) + "}";
> +    }
> +
> +    private String getBeginIndentionWithReturnForList(int n) {
> +        return "[" + getEol() + getIndention(n);
> +    }
> +
> +    private String getEndIndentionWithReturnForList(int n) {
> +        return getEol() + getIndention(n) + "]";
> +    }
> +
> +    /*private String getEndIndentionWithoutReturnForList(int n) {
> +        return getIndention(n) + "]";
> +    }
> +
> +    private String getEndIndentionWithoutReturn(int n) {
> +        return getIndention(n) + "}";
> +    }*/
> +
> +    private String getIndention(int n) {
> +        String ret = "";
> +        for (int i = 0; i < n; i++) {
> +            ret = ret + INDENTION;
> +        }
> +        return ret;
> +    }
> +
> +    private String getEol() {
> +        if (eol == null) {
> +            return "\n";
> +        } else {
> +            return this.eol;
> +        }
> +    }
> +
> +    private ConfigurationAdmin getConfigurationAdmin() {
> +        try {
> +            if (isInOSGi() && (configurationAdmin == null)) {
> +                BundleContext bundleContext = FrameworkUtil.getBundle(ManagedEndpoint.class)
> +                    .getBundleContext();
> +                if (bundleContext != null) {
> +                    ServiceReference serviceReference = bundleContext
> +                        .getServiceReference(ConfigurationAdmin.class.getName());
> +                    if (serviceReference != null) {
> +                        configurationAdmin = (ConfigurationAdmin)bundleContext.getService(serviceReference);
> +                    }
> +                }
> +
> +            }
> +        } catch (Exception e) {
> +            LOG.log(Level.WARNING, "getConfigurationAdmin failed.", e);
> +        }
> +        return configurationAdmin;
> +    }
>
>       public ObjectName getObjectName() throws JMException {
>           String busId = bus.getId();
>
> http://git-wip-us.apache.org/repos/asf/cxf/blob/99eb3de3/parent/pom.xml
> ----------------------------------------------------------------------
> diff --git a/parent/pom.xml b/parent/pom.xml
> index 419d3f4..c128469 100644
> --- a/parent/pom.xml
> +++ b/parent/pom.xml
> @@ -188,6 +188,7 @@
>           <cxf.dom4j.bundle.version>1.6.1_5</cxf.dom4j.bundle.version>
>           <cxf.jdom.bundle.version>1.1_4</cxf.jdom.bundle.version>
>           <cxf.olingo.version>1.1.0</cxf.olingo.version>
> +        <cxf.jackson.version>2.3.0-rc1</cxf.jackson.version>
>           <cxf.checkstyle.extension />
>           <cxf.jaxb.context.class />
>           <cxf.spring.validation.mode>VALIDATION_AUTO</cxf.spring.validation.mode>
> @@ -1616,7 +1617,26 @@
>                   <artifactId>swagger-jaxrs_2.10</artifactId>
>                   <version>${cxf.swagger.version}</version>
>               </dependency>
> -
> +            <dependency>
> +                <groupId>com.fasterxml.jackson.module</groupId>
> +                <artifactId>jackson-module-jaxb-annotations</artifactId>
> +                <version>${cxf.jackson.version}</version>
> +            </dependency>
> +            <dependency>
> +                <groupId>com.fasterxml.jackson.core</groupId>
> +                <artifactId>jackson-databind</artifactId>
> +                <version>${cxf.jackson.version}</version>
> +            </dependency>
> +            <dependency>
> +                <groupId>com.fasterxml.jackson.core</groupId>
> +                <artifactId>jackson-annotations</artifactId>
> +                <version>${cxf.jackson.version}</version>
> +            </dependency>
> +            <dependency>
> +                <groupId>com.fasterxml.jackson.core</groupId>
> +                <artifactId>jackson-core</artifactId>
> +                <version>${cxf.jackson.version}</version>
> +            </dependency>
>           </dependencies>
>       </dependencyManagement>
>       <profiles>
>
> http://git-wip-us.apache.org/repos/asf/cxf/blob/99eb3de3/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/AbstractJAXRSFactoryBean.java
> ----------------------------------------------------------------------
> diff --git a/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/AbstractJAXRSFactoryBean.java b/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/AbstractJAXRSFactoryBean.java
> index 4ee0127..e8e1f1a 100644
> --- a/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/AbstractJAXRSFactoryBean.java
> +++ b/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/AbstractJAXRSFactoryBean.java
> @@ -18,12 +18,14 @@
>    */
>   package org.apache.cxf.jaxrs;
>
> +import java.lang.reflect.Type;
>   import java.util.ArrayList;
>   import java.util.Arrays;
>   import java.util.Collections;
>   import java.util.Iterator;
>   import java.util.LinkedList;
>   import java.util.List;
> +import java.util.Map;
>   import java.util.ResourceBundle;
>   import java.util.logging.Logger;
>
> @@ -66,7 +68,8 @@ public class AbstractJAXRSFactoryBean extends AbstractEndpointFactory {
>
>       private static final Logger LOG = LogUtils.getL7dLogger(AbstractJAXRSFactoryBean.class);
>       private static final ResourceBundle BUNDLE = BundleUtils.getBundle(AbstractJAXRSFactoryBean.class);
> -
> +    private static final String RESOURCE_TYPES = "jaxrs.resource.types";
> +
>       protected List<String> schemaLocations;
>       protected JAXRSServiceFactoryBean serviceFactory;
>       protected List<Object> entityProviders = new LinkedList<Object>();
> @@ -241,6 +244,9 @@ public class AbstractJAXRSFactoryBean extends AbstractEndpointFactory {
>                                        cri.getServiceClass(), null);
>           }
>           ep.put(JAXRSServiceFactoryBean.class.getName(), serviceFactory);
> +        Map<Class<?>, Type> allClasses =
> +            ResourceUtils.getAllRequestResponseTypes(list, false).getAllTypes();
> +        ep.put(RESOURCE_TYPES, allClasses.keySet());
>           return ep;
>       }
>
>
> http://git-wip-us.apache.org/repos/asf/cxf/blob/99eb3de3/rt/pom.xml
> ----------------------------------------------------------------------
> diff --git a/rt/pom.xml b/rt/pom.xml
> index 8472491..761cedc 100644
> --- a/rt/pom.xml
> +++ b/rt/pom.xml
> @@ -49,7 +49,6 @@
>           <module>transports/http-netty/netty-server</module>
>           <module>transports/http-netty/netty-client</module>
>           <module>transports/jms</module>
> -        <module>transports/udp</module>
>           <module>transports/websocket</module>
>           <module>ws/policy</module>
>           <module>ws/addr</module>
>
> http://git-wip-us.apache.org/repos/asf/cxf/blob/99eb3de3/rt/rs/description/src/main/java/org/apache/cxf/jaxrs/model/wadl/WadlGenerator.java
> ----------------------------------------------------------------------
> diff --git a/rt/rs/description/src/main/java/org/apache/cxf/jaxrs/model/wadl/WadlGenerator.java b/rt/rs/description/src/main/java/org/apache/cxf/jaxrs/model/wadl/WadlGenerator.java
> index a773a9f..c72af89 100644
> --- a/rt/rs/description/src/main/java/org/apache/cxf/jaxrs/model/wadl/WadlGenerator.java
> +++ b/rt/rs/description/src/main/java/org/apache/cxf/jaxrs/model/wadl/WadlGenerator.java
> @@ -205,6 +205,18 @@ public class WadlGenerator implements ContainerRequestFilter {
>
>           boolean isJson = type == MediaType.APPLICATION_JSON_TYPE;
>
> +        StringBuilder sbMain = generateWADL(getBaseURI(m, ui), getResourcesList(m, ui), isJson, m, ui);
> +
> +        m.getExchange().put(JAXRSUtils.IGNORE_MESSAGE_WRITERS, !isJson && ignoreMessageWriters);
> +        Response r = Response.ok().type(type).entity(createResponseEntity(sbMain.toString(), isJson)).build();
> +        context.abortWith(r);
> +    }
> +
> +    public StringBuilder generateWADL(String baseURI,
> +                                       List<ClassResourceInfo> cris,
> +                                       boolean isJson,
> +                                       Message m,
> +                                       UriInfo ui) {
>           StringBuilder sbMain = new StringBuilder();
>           sbMain.append("<application");
>           if (!isJson) {
> @@ -215,11 +227,10 @@ public class WadlGenerator implements ContainerRequestFilter {
>           sbGrammars.append("<grammars>");
>
>           StringBuilder sbResources = new StringBuilder();
> -        sbResources.append("<resources base=\"").append(getBaseURI(m, ui)).append("\">");
> +        sbResources.append("<resources base=\"").append(baseURI).append("\">");
>
> -        List<ClassResourceInfo> cris = getResourcesList(m, ui);
> -
> -        MessageBodyWriter<?> jaxbWriter = useJaxbContextForQnames
> +
> +        MessageBodyWriter<?> jaxbWriter = (m != null && useJaxbContextForQnames)
>               ? ServerProviderFactory.getInstance(m).getRegisteredJaxbWriter() : null;
>           ResourceTypes resourceTypes = ResourceUtils.getAllRequestResponseTypes(cris,
>                                                                                  useJaxbContextForQnames,
> @@ -262,10 +273,7 @@ public class WadlGenerator implements ContainerRequestFilter {
>           sbMain.append(sbGrammars.toString());
>           sbMain.append(sbResources.toString());
>           sbMain.append("</application>");
> -
> -        m.getExchange().put(JAXRSUtils.IGNORE_MESSAGE_WRITERS, !isJson && ignoreMessageWriters);
> -        Response r = Response.ok().type(type).entity(createResponseEntity(sbMain.toString(), isJson)).build();
> -        context.abortWith(r);
> +        return sbMain;
>       }
>
>       private Object createResponseEntity(String entity, boolean isJson) {
>
> http://git-wip-us.apache.org/repos/asf/cxf/blob/99eb3de3/rt/rs/description/src/main/java/org/apache/cxf/jaxrs/swagger/SwaggerFeature.java
> ----------------------------------------------------------------------
> diff --git a/rt/rs/description/src/main/java/org/apache/cxf/jaxrs/swagger/SwaggerFeature.java b/rt/rs/description/src/main/java/org/apache/cxf/jaxrs/swagger/SwaggerFeature.java
> index 85e3dd3..c772559 100644
> --- a/rt/rs/description/src/main/java/org/apache/cxf/jaxrs/swagger/SwaggerFeature.java
> +++ b/rt/rs/description/src/main/java/org/apache/cxf/jaxrs/swagger/SwaggerFeature.java
> @@ -22,8 +22,11 @@ import java.util.ArrayList;
>   import java.util.List;
>
>   import org.apache.cxf.Bus;
> +import org.apache.cxf.endpoint.EndpointImpl;
>   import org.apache.cxf.endpoint.Server;
>   import org.apache.cxf.feature.AbstractFeature;
> +import org.apache.cxf.feature.Feature;
> +import org.apache.cxf.interceptor.InterceptorProvider;
>   import org.apache.cxf.jaxrs.JAXRSServiceFactoryBean;
>   import org.apache.cxf.jaxrs.model.AbstractResourceInfo;
>   import org.apache.cxf.jaxrs.provider.ProviderFactory;
> @@ -80,6 +83,21 @@ public class SwaggerFeature extends AbstractFeature {
>               setBasePath(address + "/api-docs");
>           }
>       }
> +
> +    @Override
> +    protected void initializeProvider(InterceptorProvider provider, Bus bus) {
> +        EndpointImpl endpointImpl = (EndpointImpl)provider;
> +        List<Feature> features = endpointImpl.getActiveFeatures();
> +        if (features == null) {
> +            features = new ArrayList<Feature>();
> +            features.add(this);
> +            endpointImpl.initializeActiveFeatures(features);
> +        } else {
> +            features.add(this);
> +        }
> +    }
> +
> +
>       public String getResourcePackage() {
>           return resourcePackage;
>       }
>
> http://git-wip-us.apache.org/repos/asf/cxf/blob/99eb3de3/services/pom.xml
> ----------------------------------------------------------------------
> diff --git a/services/pom.xml b/services/pom.xml
> index f7b49d4..34c3c09 100644
> --- a/services/pom.xml
> +++ b/services/pom.xml
> @@ -31,7 +31,6 @@
>           <version>3.0.0-SNAPSHOT</version>
>       </parent>
>       <modules>
> -        <module>sts</module>
>           <module>wsn</module>
>           <module>ws-discovery</module>
>           <module>xkms</module>
>
> http://git-wip-us.apache.org/repos/asf/cxf/blob/99eb3de3/services/xkms/pom.xml
> ----------------------------------------------------------------------
> diff --git a/services/xkms/pom.xml b/services/xkms/pom.xml
> index e7c9fa7..14d6011 100644
> --- a/services/xkms/pom.xml
> +++ b/services/xkms/pom.xml
> @@ -39,6 +39,5 @@
>           <module>xkms-features</module>
>           <module>xkms-osgi</module>
>           <module>xkms-war</module>
> -        <module>xkms-itests</module>
>       </modules>
>   </project>
>
> http://git-wip-us.apache.org/repos/asf/cxf/blob/99eb3de3/systests/jaxrs/pom.xml
> ----------------------------------------------------------------------
> diff --git a/systests/jaxrs/pom.xml b/systests/jaxrs/pom.xml
> index 6f66d90..81f7ec0 100644
> --- a/systests/jaxrs/pom.xml
> +++ b/systests/jaxrs/pom.xml
> @@ -415,6 +415,27 @@
>               <version>${cxf.netty3.version}</version>
>               <scope>test</scope>
>           </dependency>
> +        <dependency>
> +            <groupId>com.fasterxml.jackson.core</groupId>
> +            <artifactId>jackson-core</artifactId>
> +            <scope>test</scope>
> +        </dependency>
> +        <dependency>
> +            <groupId>com.fasterxml.jackson.core</groupId>
> +            <artifactId>jackson-databind</artifactId>
> +            <scope>test</scope>
> +        </dependency>
> +        <dependency>
> +            <groupId>com.fasterxml.jackson.module</groupId>
> +            <artifactId>jackson-module-jaxb-annotations</artifactId>
> +            <scope>test</scope>
> +        </dependency>
> +        <dependency>
> +            <groupId>javax.validation</groupId>
> +            <artifactId>validation-api</artifactId>
> +            <scope>test</scope>
> +        </dependency>
> +
>       </dependencies>
>       <build>
>           <plugins>
>
> http://git-wip-us.apache.org/repos/asf/cxf/blob/99eb3de3/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/RestJsonSchemaJMXTest.java
> ----------------------------------------------------------------------
> diff --git a/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/RestJsonSchemaJMXTest.java b/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/RestJsonSchemaJMXTest.java
> new file mode 100644
> index 0000000..04926c7
> --- /dev/null
> +++ b/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/RestJsonSchemaJMXTest.java
> @@ -0,0 +1,162 @@
> +/**
> + * Licensed to the Apache Software Foundation (ASF) under one
> + * or more contributor license agreements. See the NOTICE file
> + * distributed with this work for additional information
> + * regarding copyright ownership. The ASF licenses this file
> + * to you under the Apache License, Version 2.0 (the
> + * "License"); you may not use this file except in compliance
> + * with the License. You may obtain a copy of the License at
> + *
> + * http://www.apache.org/licenses/LICENSE-2.0
> + *
> + * Unless required by applicable law or agreed to in writing,
> + * software distributed under the License is distributed on an
> + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
> + * KIND, either express or implied. See the License for the
> + * specific language governing permissions and limitations
> + * under the License.
> + */
> +
> +package org.apache.cxf.systest.jaxrs;
> +
> +
> +import java.io.IOException;
> +import java.util.Iterator;
> +import java.util.Set;
> +import java.util.logging.Logger;
> +
> +import javax.management.MBeanServerConnection;
> +import javax.management.MalformedObjectNameException;
> +import javax.management.ObjectName;
> +import javax.management.remote.JMXConnector;
> +import javax.management.remote.JMXConnectorFactory;
> +import javax.management.remote.JMXServiceURL;
> +
> +import com.fasterxml.jackson.core.JsonFactory;
> +import com.fasterxml.jackson.core.JsonParser;
> +
> +import org.apache.cxf.Bus;
> +import org.apache.cxf.BusFactory;
> +import org.apache.cxf.bus.spring.SpringBusFactory;
> +import org.apache.cxf.common.logging.LogUtils;
> +import org.apache.cxf.endpoint.Server;
> +import org.apache.cxf.helpers.CastUtils;
> +import org.apache.cxf.jaxrs.JAXRSServerFactoryBean;
> +import org.apache.cxf.jaxrs.lifecycle.SingletonResourceProvider;
> +import org.apache.cxf.management.ManagementConstants;
> +import org.apache.cxf.testutil.common.AbstractBusClientServerTestBase;
> +import org.apache.cxf.transport.local.LocalTransportFactory;
> +
> +import org.junit.After;
> +import org.junit.Before;
> +import org.junit.Test;
> +
> +public class RestJsonSchemaJMXTest extends AbstractBusClientServerTestBase {
> +
> +    private static MBeanServerConnection mbsc;
> +    private static final String DEFAULT_JMXSERVICE_URL =
> +        "service:jmx:rmi:///jndi/rmi://localhost:9914/jmxrmi";
> +    private static final Logger LOG = LogUtils.getL7dLogger(RestJsonSchemaJMXTest.class);
> +
> +
> +    private String jmxServerURL;
> +
> +    private Server localServer;
> +
> +    @Before
> +    public void setUp() {
> +        SpringBusFactory bf = new SpringBusFactory();
> +        Bus bus = bf
> +                .createBus("/org/apache/cxf/systest/jaxrs/jmx-enable.xml");
> +        BusFactory.setDefaultBus(bus);
> +        JAXRSServerFactoryBean sf = new JAXRSServerFactoryBean();
> +        sf.setResourceClasses(BookStore.class, BookStoreSpring.class);
> +        sf.setResourceProvider(BookStore.class,
> +                               new SingletonResourceProvider(new BookStore(), true));
> +        sf.setResourceProvider(BookStoreSpring.class,
> +                               new SingletonResourceProvider(new BookStoreSpring(), true));
> +        sf.setTransportId(LocalTransportFactory.TRANSPORT_ID);
> +        sf.setAddress("local://books");
> +        localServer = sf.create();
> +    }
> +
> +    @After
> +    public void tearDown() {
> +        if (localServer != null) {
> +            localServer.stop();
> +        }
> +    }
> +
> +    @Test
> +    public void testJsonSchema() throws Exception {
> +        String json = "";
> +        try {
> +            connectToMBserver();
> +            //test getJSONSchema
> +            json = invokeEndpoint("getJSONSchema", null);
> +            parseJson(json);
> +
> +            //test getJSONSchemaForClass
> +            json = invokeEndpoint("getJSONSchemaForClass", "org.apache.cxf.systest.jaxrs.Book");
> +            parseJson(json);
> +        } catch (Throwable e) {
> +            e.printStackTrace();
> +            fail("invalid json for " + json);
> +        }
> +    }
> +
> +    private void connectToMBserver() throws IOException {
> +        jmxServerURL = jmxServerURL == null ? DEFAULT_JMXSERVICE_URL : jmxServerURL;
> +        JMXServiceURL url = new JMXServiceURL(jmxServerURL);
> +        JMXConnector jmxc = JMXConnectorFactory.connect(url, null);
> +        mbsc = jmxc.getMBeanServerConnection();
> +    }
> +
> +    private ObjectName getEndpointObjectName()
> +        throws MalformedObjectNameException, NullPointerException {
> +        StringBuilder buffer = new StringBuilder();
> +        String serviceName = "{http://jaxrs.systest.cxf.apache.org/}BookStore";
> +        String portName = "BookStore";
> +        buffer.append(ManagementConstants.DEFAULT_DOMAIN_NAME + ":type=Bus.Service.Endpoint,");
> +        buffer.append(ManagementConstants.SERVICE_NAME_PROP + "=\"" + serviceName + "\",");
> +        buffer.append(ManagementConstants.PORT_NAME_PROP + "=\"" + portName + "\",*");
> +        return new ObjectName(buffer.toString());
> +    }
> +
> +    private String invokeEndpoint(String operation, String operationPara)
> +        throws Exception {
> +        ObjectName endpointName = null;
> +        ObjectName queryEndpointName;
> +        String ret = "";
> +        Object[] jmxPara = null;
> +        String[] jmxSig = null;
> +        if (operationPara != null) {
> +            jmxPara = new Object[]{operationPara};
> +            jmxSig = new String[] {String.class.getName()};
> +        } else {
> +            jmxPara = new Object[0];
> +            jmxSig = new String[0];
> +        }
> +        queryEndpointName = getEndpointObjectName();
> +        Set<ObjectName> endpointNames = CastUtils.cast(mbsc.queryNames(queryEndpointName, null));
> +        // now get the ObjectName with the busId
> +        Iterator<ObjectName> it = endpointNames.iterator();
> +
> +        if (it.hasNext()) {
> +            // only deal with the first endpoint object which retrun from the list.
> +            endpointName = it.next();
> +            ret = (String)mbsc.invoke(endpointName, operation, jmxPara, jmxSig);
> +            LOG.info("invoke endpoint " + endpointName
> +                               + " operation " + operation + " succeed!");
> +        }
> +        return ret;
> +    }
> +
> +    private void parseJson(String json) throws Exception {
> +        JsonParser parser = new JsonFactory().createParser(json);
> +        while (parser.nextToken() != null) {
> +            //if it's an invalidate json will throw exception
> +            //which could be caught by the test
> +        }
> +    }
> +}
>
> http://git-wip-us.apache.org/repos/asf/cxf/blob/99eb3de3/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/jmx-enable.xml
> ----------------------------------------------------------------------
> diff --git a/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/jmx-enable.xml b/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/jmx-enable.xml
> new file mode 100644
> index 0000000..da799fd
> --- /dev/null
> +++ b/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/jmx-enable.xml
> @@ -0,0 +1,16 @@
> +<beans xmlns="http://www.springframework.org/schema/beans"
> +  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
> +  xmlns:cxf="http://cxf.apache.org/core"
> +  xsi:schemaLocation="
> +           http://www.springframework.org/schema/beans
> +              http://www.springframework.org/schema/beans/spring-beans.xsd
> +           http://cxf.apache.org/core
> +              http://cxf.apache.org/schemas/core.xsd">
> +
> +    <cxf:bus bus="cxf">
> +      <cxf:properties>
> +          <entry key="bus.jmx.enabled" value="true"/>
> +          <entry key="bus.jmx.JMXServiceURL" value="service:jmx:rmi:///jndi/rmi://localhost:9914/jmxrmi" />
> +      </cxf:properties>
> +    </cxf:bus>
> +</beans>
>
> http://git-wip-us.apache.org/repos/asf/cxf/blob/99eb3de3/systests/jaxws/pom.xml
> ----------------------------------------------------------------------
> diff --git a/systests/jaxws/pom.xml b/systests/jaxws/pom.xml
> index d8ee05f..2802d23 100644
> --- a/systests/jaxws/pom.xml
> +++ b/systests/jaxws/pom.xml
> @@ -224,6 +224,27 @@
>               </exclusions>
>               <scope>test</scope>
>           </dependency>
> +        <dependency>
> +            <groupId>com.fasterxml.jackson.core</groupId>
> +            <artifactId>jackson-core</artifactId>
> +            <scope>test</scope>
> +        </dependency>
> +        <dependency>
> +            <groupId>com.fasterxml.jackson.core</groupId>
> +            <artifactId>jackson-databind</artifactId>
> +            <scope>test</scope>
> +        </dependency>
> +        <dependency>
> +            <groupId>com.fasterxml.jackson.module</groupId>
> +            <artifactId>jackson-module-jaxb-annotations</artifactId>
> +            <scope>test</scope>
> +        </dependency>
> +        <dependency>
> +            <groupId>javax.validation</groupId>
> +            <artifactId>validation-api</artifactId>
> +            <scope>test</scope>
> +        </dependency>
> +
>       </dependencies>
>       <profiles>
>           <profile>
>
> http://git-wip-us.apache.org/repos/asf/cxf/blob/99eb3de3/systests/jaxws/src/test/java/org/apache/cxf/systest/jaxws/JsonSchemaJMXTest.java
> ----------------------------------------------------------------------
> diff --git a/systests/jaxws/src/test/java/org/apache/cxf/systest/jaxws/JsonSchemaJMXTest.java b/systests/jaxws/src/test/java/org/apache/cxf/systest/jaxws/JsonSchemaJMXTest.java
> new file mode 100644
> index 0000000..ec5b2c0
> --- /dev/null
> +++ b/systests/jaxws/src/test/java/org/apache/cxf/systest/jaxws/JsonSchemaJMXTest.java
> @@ -0,0 +1,146 @@
> +/**
> + * Licensed to the Apache Software Foundation (ASF) under one
> + * or more contributor license agreements. See the NOTICE file
> + * distributed with this work for additional information
> + * regarding copyright ownership. The ASF licenses this file
> + * to you under the Apache License, Version 2.0 (the
> + * "License"); you may not use this file except in compliance
> + * with the License. You may obtain a copy of the License at
> + *
> + * http://www.apache.org/licenses/LICENSE-2.0
> + *
> + * Unless required by applicable law or agreed to in writing,
> + * software distributed under the License is distributed on an
> + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
> + * KIND, either express or implied. See the License for the
> + * specific language governing permissions and limitations
> + * under the License.
> + */
> +
> +package org.apache.cxf.systest.jaxws;
> +
> +import java.io.IOException;
> +import java.util.Iterator;
> +import java.util.Set;
> +import java.util.logging.Logger;
> +
> +import javax.management.MBeanServerConnection;
> +import javax.management.MalformedObjectNameException;
> +import javax.management.ObjectName;
> +import javax.management.remote.JMXConnector;
> +import javax.management.remote.JMXConnectorFactory;
> +import javax.management.remote.JMXServiceURL;
> +import javax.xml.ws.Endpoint;
> +
> +import com.fasterxml.jackson.core.JsonFactory;
> +import com.fasterxml.jackson.core.JsonParser;
> +
> +import org.apache.cxf.Bus;
> +import org.apache.cxf.BusFactory;
> +import org.apache.cxf.bus.spring.SpringBusFactory;
> +import org.apache.cxf.common.logging.LogUtils;
> +import org.apache.cxf.helpers.CastUtils;
> +import org.apache.cxf.management.ManagementConstants;
> +import org.apache.cxf.testutil.common.TestUtil;
> +
> +import org.apache.hello_world.GreeterImpl;
> +
> +
> +import org.junit.Assert;
> +import org.junit.Test;
> +
> +public class JsonSchemaJMXTest extends Assert {
> +
> +    static final String PORT = TestUtil.getPortNumber(JsonSchemaJMXTest.class);
> +    private static MBeanServerConnection mbsc;
> +    private static final String DEFAULT_JMXSERVICE_URL =
> +        "service:jmx:rmi:///jndi/rmi://localhost:9914/jmxrmi";
> +    private static final Logger LOG = LogUtils.getL7dLogger(JsonSchemaJMXTest.class);
> +
> +
> +    private String jmxServerURL;
> +
> +    @Test
> +    public void testJMXGetJsonSchema() throws Exception {
> +        SpringBusFactory bf = new SpringBusFactory();
> +        Bus bus = bf
> +                .createBus("/org/apache/cxf/systest/jaxws/jmx-enable.xml");
> +        BusFactory.setDefaultBus(bus);
> +        Endpoint ep = Endpoint.publish("http://localhost:" + PORT + "/SoapContext/SoapPort",
> +                                       new GreeterImpl());
> +        String json = "";
> +        try {
> +            connectToMBserver();
> +            //test getJSONSchema
> +            json = invokeEndpoint("getJSONSchema", null);
> +            parseJson(json);
> +            //test getJSONSchemaForClass
> +            json = invokeEndpoint("getJSONSchemaForClass", "SayHi");
> +            parseJson(json);
> +            //test getJSONSchemaForOperation
> +            json = invokeEndpoint("getJSONSchemaForOperation", "greetMe");
> +            parseJson(json);
> +        } catch (Throwable e) {
> +            e.printStackTrace();
> +            fail("invalid json for " + json);
> +        } finally {
> +            ep.stop();
> +        }
> +    }
> +
> +    private void connectToMBserver() throws IOException {
> +        jmxServerURL = jmxServerURL == null ? DEFAULT_JMXSERVICE_URL : jmxServerURL;
> +        JMXServiceURL url = new JMXServiceURL(jmxServerURL);
> +        JMXConnector jmxc = JMXConnectorFactory.connect(url, null);
> +        mbsc = jmxc.getMBeanServerConnection();
> +    }
> +
> +    private ObjectName getEndpointObjectName()
> +        throws MalformedObjectNameException, NullPointerException {
> +        StringBuilder buffer = new StringBuilder();
> +        String serviceName = "{http://apache.org/hello_world/services}SOAPService";
> +        String portName = "SoapPort";
> +        buffer.append(ManagementConstants.DEFAULT_DOMAIN_NAME + ":type=Bus.Service.Endpoint,");
> +        buffer.append(ManagementConstants.SERVICE_NAME_PROP + "=\"" + serviceName + "\",");
> +        buffer.append(ManagementConstants.PORT_NAME_PROP + "=\"" + portName + "\",*");
> +        return new ObjectName(buffer.toString());
> +    }
> +
> +    private String invokeEndpoint(String operation, String operationPara)
> +        throws Exception {
> +        ObjectName endpointName = null;
> +        ObjectName queryEndpointName;
> +        String ret = "";
> +        Object[] jmxPara = null;
> +        String[] jmxSig = null;
> +        if (operationPara != null) {
> +            jmxPara = new Object[]{operationPara};
> +            jmxSig = new String[] {String.class.getName()};
> +        } else {
> +            jmxPara = new Object[0];
> +            jmxSig = new String[0];
> +        }
> +        queryEndpointName = getEndpointObjectName();
> +        Set<ObjectName> endpointNames = CastUtils.cast(mbsc.queryNames(queryEndpointName, null));
> +        // now get the ObjectName with the busId
> +        Iterator<ObjectName> it = endpointNames.iterator();
> +
> +        if (it.hasNext()) {
> +            // only deal with the first endpoint object which retrun from the list.
> +            endpointName = it.next();
> +            ret = (String)mbsc.invoke(endpointName, operation, jmxPara, jmxSig);
> +            LOG.info("invoke endpoint " + endpointName
> +                               + " operation " + operation + " succeed!");
> +        }
> +        return ret;
> +    }
> +
> +    private void parseJson(String json) throws Exception {
> +        JsonParser parser = new JsonFactory().createParser(json);
> +        while (parser.nextToken() != null) {
> +            //if it's an invalidate json will throw exception
> +            //which could be caught by the test
> +        }
> +    }
> +
> +}
>
> http://git-wip-us.apache.org/repos/asf/cxf/blob/99eb3de3/systests/jaxws/src/test/java/org/apache/cxf/systest/jaxws/jmx-enable.xml
> ----------------------------------------------------------------------
> diff --git a/systests/jaxws/src/test/java/org/apache/cxf/systest/jaxws/jmx-enable.xml b/systests/jaxws/src/test/java/org/apache/cxf/systest/jaxws/jmx-enable.xml
> new file mode 100644
> index 0000000..fad676d
> --- /dev/null
> +++ b/systests/jaxws/src/test/java/org/apache/cxf/systest/jaxws/jmx-enable.xml
> @@ -0,0 +1,28 @@
> +<beans xmlns="http://www.springframework.org/schema/beans"
> +  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
> +  xmlns:sec="http://cxf.apache.org/configuration/security"
> +  xmlns:http="http://cxf.apache.org/transports/http/configuration"
> +  xmlns:httpj="http://cxf.apache.org/transports/http-jetty/configuration"
> +  xmlns:jaxws="http://cxf.apache.org/jaxws"
> +  xmlns:cxf="http://cxf.apache.org/core"
> +  xsi:schemaLocation="
> +                   http://cxf.apache.org/configuration/security
> +                      http://cxf.apache.org/schemas/configuration/security.xsd
> +           http://cxf.apache.org/transports/http/configuration
> +              http://cxf.apache.org/schemas/configuration/http-conf.xsd
> +           http://cxf.apache.org/transports/http-jetty/configuration
> +              http://cxf.apache.org/schemas/configuration/http-jetty.xsd
> +           http://cxf.apache.org/jaxws
> +              http://cxf.apache.org/schemas/jaxws.xsd
> +           http://www.springframework.org/schema/beans
> +              http://www.springframework.org/schema/beans/spring-beans.xsd
> +           http://cxf.apache.org/core
> +              http://cxf.apache.org/schemas/core.xsd">
> +
> +    <cxf:bus bus="cxf">
> +      <cxf:properties>
> +          <entry key="bus.jmx.enabled" value="true"/>
> +          <entry key="bus.jmx.JMXServiceURL" value="service:jmx:rmi:///jndi/rmi://localhost:9914/jmxrmi" />
> +      </cxf:properties>
> +    </cxf:bus>
> +</beans>
>


-- 
Sergey Beryozkin

Talend Community Coders
http://coders.talend.com/

Blog: http://sberyozkin.blogspot.com

Re: git commit: [CXF-5661]add more JMX operations for ManagedEndpoint mbean

Posted by Sergey Beryozkin <sb...@gmail.com>.
On 01/04/14 10:46, Sergey Beryozkin wrote:
> Hi Freeman
>
> IMHO it appears to be a rather 'intrusive' commit. I'm sure it will help
> with the JMX improvements work somehow but here are some comments:
>
> Here are some comments:
> - should your bean annotation introspectors to do with JMX be moved to
> rt/management, do they belong to the core ? All these Jackson deps just
> hit the eye :-), nothing against Jackson here per se, just seems it is
> not in the right place
Yeah, ManagedEndpoint is in the core - may be it can be migrated into 
rt/management in 3.0 ?

Cheers, Sergey
> - AbstractJAXRSFactoryBean update: I don't think we need to keep the
> custom classes map within every created endpoint by default for the sake
> of the optional JMX improvement: if you need it for the JMX work then
> lets consider how this can be optionally done, example, add a service
> endpoint listener and add the classes map from there, etc, so lets
> remove those lines for now
>
> Thanks, Sergey
>