I am trying set up swagger in a non-maven java jetty-web application.
I have taken all the dependency jar files from the git repositories and included them in my web app WEB-INF/lib directory.
Yet I am unable to access localhost:7443/api/swagger.json
Fyi, In my webapp I use jersey 1.x and jax-rs.
I have followed multiple ways to set up as given in the documentation.
Approach-1:
The web-xml way:
I have added the swagger initialization and references in the web xml like this:
<servlet>
<servlet-name>jersey</servlet-name>
<servlet-class>com.sun.jersey.spi.container.servlet.ServletContainer</servlet-class>
<init-param>
<param-name>com.sun.jersey.config.property.packages</param-name>
<param-value>
io.swagger.jaxrs.json,
io.swagger.jaxrs.listing,
com.myproject.rest
</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>jersey</servlet-name>
<url-pattern>/api/*</url-pattern>
</servlet-mapping>
<servlet>
<servlet-name>Jersey2Config</servlet-name>
<servlet-class>io.swagger.jaxrs.config.DefaultJaxrsConfig</servlet-class>
<init-param>
<param-name>api.version</param-name>
<param-value>1.0.0</param-value>
</init-param>
<init-param>
<param-name>swagger.api.basepath</param-name>
<param-value>https://localhost:7443/api</param-value>
</init-param>
<load-on-startup>2</load-on-startup>
</servlet>
....some more servlets and filters defined after this
The build and run were successful and my web-app comes up like as usual. I see these log lines during the runtime:
15:53:36,837 |-INFO in ch.qos.logback.classic.LoggerContext[default] - Could NOT find resource [logback.groovy]
15:53:36,837 |-INFO in ch.qos.logback.classic.LoggerContext[default] - Found resource [logback-test.xml] at [jar:file:/Users/vinayabhishek/Documents/TCPWave/workspace/tims/WebContent/WEB-INF/lib/swagger-core-1.5.11-SNAPSHOT-tests.jar!/logback-test.xml]
15:53:36,848 |-INFO in ch.qos.logback.core.joran.spi.ConfigurationWatchList#32c26e28 - URL [jar:file:/Users/vinayabhishek/Documents/TCPWave/workspace/tims/WebContent/WEB-INF/lib/swagger-core-1.5.11-SNAPSHOT-tests.jar!/logback-test.xml] is not of type file
15:53:36,866 |-INFO in ch.qos.logback.classic.joran.action.ConfigurationAction - debug attribute not set
15:53:37,172 |-INFO in ch.qos.logback.core.joran.action.AppenderAction - About to instantiate appender of type [ch.qos.logback.core.ConsoleAppender]
15:53:37,175 |-INFO in ch.qos.logback.core.joran.action.AppenderAction - Naming appender as [STDOUT]
15:53:37,225 |-WARN in ch.qos.logback.core.ConsoleAppender[STDOUT] - This appender no longer admits a layout as a sub-component, set an encoder instead.
15:53:37,225 |-WARN in ch.qos.logback.core.ConsoleAppender[STDOUT] - To ensure compatibility, wrapping your layout in LayoutWrappingEncoder.
15:53:37,225 |-WARN in ch.qos.logback.core.ConsoleAppender[STDOUT] - See also http://logback.qos.ch/codes.html#layoutInsteadOfEncoder for details
15:53:37,225 |-INFO in ch.qos.logback.classic.joran.action.LoggerAction - Setting level of logger [io.swagger] to ERROR
15:53:37,225 |-INFO in ch.qos.logback.classic.joran.action.RootLoggerAction - Setting level of ROOT logger to ERROR
15:53:37,225 |-INFO in ch.qos.logback.core.joran.action.AppenderRefAction - Attaching appender named [STDOUT] to Logger[ROOT]
15:53:37,226 |-INFO in ch.qos.logback.classic.joran.action.ConfigurationAction - End of configuration.
15:53:37,227 |-INFO in ch.qos.logback.classic.joran.JoranConfigurator#5e9771a5 - Registering current configuration as safe fallback point
However https://localhost:7443/api/swagger.json gives me 404 response.
Approach 2: The Custom Application class
I have defined a custom SampleApplication.java class that looks like this
public class SampleApplication extends Application {
public SampleApplication() {
BeanConfig beanConfig = new BeanConfig();
beanConfig.setVersion("1.0.2");
beanConfig.setSchemes(new String[]{"http"});
beanConfig.setHost("localhost:8002");
beanConfig.setBasePath("/api");
beanConfig.setResourcePackage("io.swagger.resources");
beanConfig.setScan(true);
System.out.println("Did we set it?");
}
#Override
public Set<Class<?>> getClasses() {
Set<Class<?>> resources = new HashSet<Class<?>>();
resources.add(PersonsService.class);
//resources.add(SecondResource.class);
//...
resources.add(io.swagger.jaxrs.listing.ApiListingResource.class);
resources.add(io.swagger.jaxrs.listing.SwaggerSerializers.class);
return resources;
}
}
This also did not work. I do not see any errors in the stack trace except for the logback stuff listed above.
I have also added annotations to one of my WebService class like this:
#Path("/people")
#Api( value = "/people", description = "Manage people" )
public class PeopleService {
#Path("/list/{city_id}")
#GET
#Consumes({ MediaType.TEXT_PLAIN })
#Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
#ApiOperation(
value = "List all people",
notes = "List all people using paging",
response = People.class,
responseContainer = "List"
)
public ArrayList<People> list(....){
}
}
I really appreciate any help on this. Thank you in advance :)
I've just had the same problem and solved it by ensuring that I was referencing the correct swagger dependency.
Originally I included swagger-core but for my Jersey 2.0 project I needed to use swagger-jersey2-jaxrs. My advice is to double check your libraries.
Related
I am having a problem where the Spring WebApplicationContext appears to be ignoring the #Import annotation on a #Configuration-annotated config class in my web app. It is not a Spring MVC web app.
The problem occurs during processing of the contextInitialized event of a custom ServletContextListener which used to be able to successfully retrieve this bean when I was using XML configuration, but is now not finding this bean now that I have (apparently incorrectly) converted to the use of #Configuration-annotated classes.
The symptoms I see are:
During app startup, I see this output from the Spring framework:
INFO: No annotated classes found for specified class/package
[org.imaginary.spring.config.Instrumented]
Later, when my contextInitialized() method is invoked and I call getBean(), I get a NoSuchBeanDefinition exception
My config classes are factored in such a way that I have, for example, two high-level config classes, one for a "Production" configuration, and another for an "Instrumented" configuration. These top-level config classes are themselves completely empty, but they make use the #Import annotation to (I'm hoping) bring in the relevant bean definitions for that kind of configuration.
For example, here is the Instrumented configuration class:
package org.imaginary.spring.config;
import org.imaginary.spring.config.instrumentation.InstrumentationDependencies;
import org.imaginary.spring.config.servlets.ServletDependencies;
#Configuration
#Import( {InstrumentationDependencies.class, ServletDependencies.class } )
public class Instrumented
{
}
...for the purposes of this example, here is the InstrumentationDependencies config class, defined in a different package:
package org.imaginary.spring.config.instrumentation;
#Configuration
public class InstrumentationDependencies
{
#Bean
public IEventSink eventSinkImpl()
{
return new InstrumentationEventSinkImpl();
}
}
Here is (a stripped-down version of) the contextInitialized() method:
#Override
public void contextInitialized( ServletContextEvent ctxEvent )
{
try
{
if (_publisher == null)
{
WebApplicationContext springContext = WebApplicationContextUtils.getWebApplicationContext(ctxEvent.getServletContext());
_eventSink = (IEventSink)springContext.getBean("eventSinkImpl");
}
_eventSink.startReceiving();
}
catch ( Exception e )
{
// handle exception
}
}
Here are the relevant entries from my web.xml:
<context-param>
<param-name>contextClass</param-name>
<param-value>
org.springframework.web.context.support.AnnotationConfigWebApplicationContext
</param-value>
</context-param>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>org.imaginary.spring.config.Instrumented</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<listener>
<listener-class>org.imaginary.MyContextListener</listener-class>
</listener>
Any ideas what I have missed?
In this case, there is nothing wrong with the Spring configuration classes or configuration. The problem was in fact a build issue - the config classes had been added to a package that wasn't getting included in the main web app jar, so the class files weren't present. I was surprised that there wasn't a NoClassDefFoundError exception thrown, as this error leaves the impression that the class exists, it just isn't annotated:
No annotated classes found for specified class/package
[your.class.here].
I have a Spring, PrimeFaces JSF application configured to load an application through a class that implements WebApplicationInitializer rather than web.xml (I do still have a bare web.xml) though. The problem is on application start and basically throughout the whole application, methods are being called twice! Best explanation I found is possible double loading of one of the listeners. I don't see I'm doing that. Attached is my WebApplicationInitializer class below. I'm not sure what to else to provide to resolve my issue. Even managed bean methods are being called twice.
public class WebAppInitializer implements WebApplicationInitializer {
#Override
public void onStartup(ServletContext servletContext) throws ServletException {
final CharacterEncodingFilter cf = new CharacterEncodingFilter();
cf.setEncoding("UTF-8");
cf.setForceEncoding(true);
servletContext.addListener(new RequestContextListener());
servletContext
.addFilter(
"ShiroFilter",
org.apache.shiro.web.servlet.IniShiroFilter.class)
.addMappingForUrlPatterns(null, false, "/*");
final WebApplicationContext context = getContext();
servletContext.addListener(new ContextLoaderListener(context));
final ServletRegistration.Dynamic dispatcher = servletContext.addServlet("DispatcherServlet", new DispatcherServlet(context));
dispatcher.setLoadOnStartup(1);
dispatcher.addMapping("*.do");
}
private AnnotationConfigWebApplicationContext getContext() {
final AnnotationConfigWebApplicationContext context = new AnnotationConfigWebApplicationContext();
context.register(AppConfig.class);
return context;
}
}
My web.xml has the standard definitions for faces and the following mapping:
.....
<context-param>
<param-name>javax.faces.DATETIMECONVERTER_DEFAULT_TIMEZONE_IS_SYSTEM_TIMEZONE</param-name>
<param-value>true</param-value>
</context-param>
.....
<!-- JSF Mapping -->
<servlet>
<servlet-name>Faces Servlet</servlet-name>
<servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>Faces Servlet</servlet-name>
<url-pattern>*.jsf</url-pattern>
<url-pattern>*.xhtml</url-pattern>
</servlet-mapping>
When the application starts up, I see output from Spring that is also duplicated!
2013-12-12T11:29:56.430-0500|INFO: [org.springframework.web.context.support.AnnotationConfigWebApplicationContext] - Refreshing Root WebApplicationContext: startup date [Thu Dec 12 11:29:56 EST 2013]; root of context hierarchy
2013-12-12T11:29:56.430-0500|INFO: [org.springframework.web.context.support.AnnotationConfigWebApplicationContext] - Refreshing Root WebApplicationContext: startup date [Thu Dec 12 11:29:56 EST 2013]; root of context hierarchy
2013-12-12T11:29:56.978-0500|INFO: [org.springframework.context.annotation.ClassPathBeanDefinitionScanner] - JSR-250 'javax.annotation.ManagedBean' found and supported for component scanning
2013-12-12T11:29:56.978-0500|INFO: [org.springframework.context.annotation.ClassPathBeanDefinitionScanner] - JSR-250 'javax.annotation.ManagedBean' found and supported for component scanning
How do I stop the duplicate calls? Thanks.
EDIT
I'm using Log4j. Here's my configuration:
log4j.rootLogger=info, A1
log4j.appender.A1=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.Target=System.out
log4j.appender.A1.layout=org.apache.log4j.PatternLayout
log4j.appender.A1.layout.ConversionPattern=[%c] %x - %m%n
log4j.logger.org.hibernate=info, A1
log4j.logger.com.telus=info, A1
log4j.logger.org.springframework=info, A1
Using Spring 3.1.4.RELEASE. PrimeFaces 4.0. JSF 2.1.7. Deployed on Glassfish 3. Java 1.6.32.
Try adding the following to your log4j.properties
log4j.additivity.org.hibernate=false
log4j.additivity.com.telus=false
log4j.additivity.org.springframework=false
That should ensure that log messages aren't duplicated by the parent root logger.
So I am tring to get a JAX-RS application working on my WebSphere 8.5 instance. I created the following interface...
#Path("service")
public class RestService {
#GET
#Produces("text/plain")
public int getCount(){
return 1;
}
}
And This is my Application...
public class RESTConfig extends Application{
#Override
public Set<Class<?>> getClasses() {
Set<Class<?>> classes = new Hashset<?>();
classes.add(RestService.class);
return classes;
}
}
And then this is my web.xml...
<servlet>
<servlet-name>Rest Servlet</servlet-name>
<servlet-class>com.ibm.websphere.jaxrs.server.IBMRestServlet</servlet-class>
<init-param>
<param-name>jaxrs.ws.rs.Application</param-name>
<param-value>com.company.rest.RESTConfig</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
....
<servlet-mapping>
<servlet-name>Rest Servlet</servlet-name>
<url-pattern>/rest/*</url-pattern>
</servlet-mapping>
Then I have an EAR configured with the WAR as a module. But when I start everything and try going to http://localhost:[port]/war/rest/app/service I see..
[TIME] 00000115 RequestProces I org.apache.wink.server.internal.RequestProcessor logException The following error occurred during the invocation of the handlers chain: WebApplicationException (404 - Not Found) with message 'null' while processing GET request sent to http://localhost:[port]/war/rest/service
Please Help!
WAS8.5 supports v2.4 and v3 servlets. The reason removing your web.xml contents (and using 3.0 code) worked for you is because you had a mistake in the param-name tag of your web.xml. v2.4 servlet works fine in WAS8.5 when you use the correct param-name.
This is incorrect.
<param-name>jaxrs.ws.rs.Application</param-name>
This is correct:
<param-name>javax.ws.rs.Application</param-name>
Details:
http://pic.dhe.ibm.com/infocenter/wasinfo/v8r5/topic/com.ibm.websphere.nd.multiplatform.doc/ae/twbs_jaxrs_configwebxml.html
The RestConfig class (that is defined as the JAX-RS Application) should override getClasses to return the resources:
#Path("app")
public class RESTConfig extends Application{
#Override
public Set<Class<?>> getClasses() {
Set<Class<?>> classes = new Hashset<?>();
classes.add(RestService.class);
return classes;
}
}
The issue appears to be related to 8.5 only supporting v3 servlets. this seems to fix the issue....
#Path("service")
public class RestService {
#GET
#Produces("text/plain")
public String getCount(){
//Text-Plain cannot be int apparently
return String.valueOf(1);
}
}
#ApplicationPath("rest")
public class RESTConfig extends Application{
//Override no longer needed.
}
This should now deploy fine...
Here was my source IBM
Also, You can try buy changing the below web.xml File
<servlet>
<servlet-name>javax.ws.rs.core.Application</servlet-name>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>javax.ws.rs.core.Application</servlet-name>
<url-pattern>/rest/*</url-pattern>
</servlet-mapping>
Also, In Project Facets - Change Web Module version to 3.0
For More Reference Visit: How to deploy a JAX-RS application?
I'm using JbossRestEasy hence i have used resteasy context loader listener in web.xml to load spring bean
<listener>
<listener-class>org.jboss.resteasy.plugins.spring.SpringContextLoaderListener
</listener-class>
</listener>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/classes/applicationContext.xml</param-value>
</context-param>
in spring configuration file
<bean id="myBean" class="com.sample.MyBean">
<property name="name" value="XYZ"/>
</bean>
public class Mybean{
private String name;
public void setName(String name) {
this.name = name;
}
public void printName(){
System.out.println("Name is -->" +name);
}
}
everything works fine if i specifically load the bean in my test case. but if i deploy it in jboss, bean is not getting injected. However, i could see that sprin config is getting loaded while server start up
12:43:40,626 INFO [STDOUT] 12:43:40,626 INFO [XmlBeanDefinitionReader] Loading XML bean definitions from ServletContext resource [/WEB-INF/classes/applicationContext.xml]
12:43:40,829 INFO [STDOUT] 12:43:40,829 INFO [DefaultListableBeanFactory] Pre-instantiating singletons in org.springframework.beans.factory.support.DefaultListableBeanFactory
It's very simple and straightforward but don't know wrong with my configuration. I'm using 3.0.5.RELEASE version of Spring.
I have configured in following way that spring MVC app using Spring 3.1.1.RELEASE
web.xml
<servlet>
<servlet-name>springmvc</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/context/*-context.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>springmvc</servlet-name>
<url-pattern>/cgi/*</url-pattern>
</servlet-mapping>
springmvc-servlet.xml
<context:component-scan base-package="com.pokuri.mvc.controllers"/>
UserController.java
package com.pokuri.mvc.controllers;
#Controller
#RequestMapping("/user")
public class UserController {
#RequestMapping(method=RequestMethod.GET)
#ResponseBody
public String defaultRequest(){
return "It's a default handler method";
}
}
index.jsp
<a class="action" href="cgi/user">Default Action</a>
Sever log on initializing springmvc app:
23:53:04,406 INFO [DispatcherServlet] FrameworkServlet 'springmvc': initialization started
23:53:04,468 INFO [XmlWebApplicationContext] Refreshing WebApplicationContext for namespace 'springmvc-servlet': startup date [Thu Jun 28 23:53:04 IST 2012]; root of context hierarchy
23:53:04,609 INFO [XmlBeanDefinitionReader] Loading XML bean definitions from ServletContext resource [/WEB-INF/context/services-context.xml]
23:53:04,890 INFO [DefaultListableBeanFactory] Pre-instantiating singletons in org.springframework.beans.factory.support.DefaultListableBeanFactory#6c4fe: defining beans [dummyService]; root of factory hierarchy
23:53:05,156 INFO [DispatcherServlet] FrameworkServlet 'springmvc': initialization completed in 750 ms
.....
.....
23:56:17,875 WARN [PageNotFound] No mapping found for HTTP request with URI [/springmvc/cgi/user] in DispatcherServlet with name 'springmvc'
When I click on that link in index.jsp, I am getting 404 error. I thing I might have done a silly mistake. But, not able to track it. Can someone help me in this?
It looks like your DispatcherServlet is looking for config files ending in -context.xml. But your Spring config file is called springmvc-servlet.xml.