-
Notifications
You must be signed in to change notification settings - Fork 4.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Make javax.servlet-api a 'provided' dependency not 'compile' #50
Make javax.servlet-api a 'provided' dependency not 'compile' #50
Conversation
…t transitive. Trying to make it so it doesn't force a servlet version or a specific jar. Nothing about the implementation requires anything higher than Servlet 2.x.
Justin (@quidryan), is this a satisfactory approach with Gradle to mark the Servlet jar as only needed for compilation but not a transitive dependency that forces builds to the declared version? The specific issue here is that Sun published 2.2 to 3.0 beta as javax.servlet:servlet-api (http://search.maven.org/#search%7Cgav%7C1%7Cg%3A%22javax.servlet%22%20AND%20a%3A%22servlet-api%22) but then Oracle published 3.0.1 onwards as javax.servlet:javax.servlet-api (http://search.maven.org/#search%7Cgav%7C1%7Cg%3A%22javax.servlet%22%20AND%20a%3A%22javax.servlet-api%22) so I can only use one of them, I can't put a range from 2+ and work with both. I have chosen 3.x as the newest (which is already 1 1/2 years old) but don't want builds forced to either one. |
There isn't a provided scope out-of-box in Gradle, so I wouldn't expect this specific merge to work. The closest is the one added by the war plugin, which adds providedRuntime and providedCompile. There are ways to replicate "provided", I'll suggest something soon for this. This merge stills implies that 3.0 of the servlet-api is available at runtime, which it might not be (i.e. using Tomcat 6). You're right that you can't simply use a range, blame Oracle for this, but since it's going into a provided scope, it's sorta moot what it's called. I would suggest sticking with 2.5 of the servlet, especially if that's all that you're using, specifically javax.servlet:servlet-api:2.5. 3.0 is different enough that it's not worth touching, e.g. it added extra bounds to the return type on getParameterMap(), which can break code. |
Justin, I thought we already had solved the 'provided' functionality, as we use it in hystrix-core => https://github.com/Netflix/Hystrix/blob/master/hystrix-core/build.gradle I'll downgrade to 2.5. |
…ency Downgrade to javax.servlet:servlet-api:2.5 instead of 3.0
The provided scope is a Hystrix thing only, i.e. it's not in gradle-template, so I wasn't too familiar with it. I'm not so sure that the way it's implemented will get you the right behavior, specifically the "compile.extendsFrom provided" line will make any dependencies still show up as dependencies, which defeats the point. I added a slightly different provided scope to the gradle-template project, I'll make a pull-request with the merge in it. |
The way I had confirmed it was working was that when I download dependencies from Maven Central for hystrix-core the JUnit jar is not included:
That is using this maven file: <?xml version="1.0"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.netflix.hystrix.download</groupId>
<artifactId>hystrix-download</artifactId>
<version>1.0-SNAPSHOT</version>
<name>Simple POM to download hystrix-core and dependencies</name>
<url>http://github.com/Netflix/Hystrix</url>
<dependencies>
<dependency>
<groupId>com.netflix.hystrix</groupId>
<artifactId>hystrix-core</artifactId>
<version>1.1.0</version>
<scope/>
</dependency>
</dependencies>
</project> |
That definitely looks good. Yeah, what you have is working. I'm going to finish up adding it to gradle-template, so at least you're in sink with the other projects. |
So would it make sense for me to also change this:
to this:
This would mean the servlet jar isn't pulled in, but the expectation is always that someone is deploying a servlet to a servlet container (Tomcat, Jetty, JBoss etc) that will already have all of those libs. |
Yes. This is one of the quirks of provided, it does imply that your users know about it. In contrast, you can put the dependency into the runtime configuration, which explicitly says you want this dependency at runtime but then most build tools will then package it up into a war, where it'll conflict with the container parent classloader. It's mostly a flaw in the original servlet specs that cause this weird situation. BTW, Java should solve something like thing via Jigsaw, and then have your war state what it wants for dependencies, and if it's already in the runtime, ignore it. |
Agreed on all of those points. For this particular case I think I'm going to do the 'provided' solution since there is never a time when running a servlet is not going to be in a container with the proper runtime libs already there. I'd rather optimize for the normal case and not cause version collisions between 2.x and 3.x - particularly because the state of Maven Central doesn't let me give a range and forces me to pick one or the other. Are you okay with me choosing that solution considering none of them are ideal? |
Sounds good. I think there is an issue with "compile.extendsFrom provided" when publishing to ivy though, but we can talk about that on the pull request I'll be making. |
Make javax.servlet-api a 'provided' dependency for compilation but not transitive.
Trying to make it so it doesn't force a servlet version or a specific jar. Nothing about the implementation requires anything higher than Servlet 2.x.