Guice Servlet config doesn't work without Servlet API - java

The following Guice Servlet configuration doesn't work when I remove the Maven dependency to the Servlet API:
filter("/*").through(TransactionFilter.class);
The compiler tells me:
cannot access javax.servlet.Filter
class file for javax.servlet.Filter not found
filter("/*").through(TransactionFilter.class);
Any idea?

What do you expect to happen when you remove the Servlet API dependency? Guice Servlet depends on the Servlet API.
Clarification edit: Guice Servlet has a provided scope dependency on the Servlet API so that the jar for it isn't pulled in to the final artifact when building an application... the API classes are provided by the application server at runtime. Thus, you must declare a dependency on the Servlet API in your application's POM yourself (preferably in provided scope as well) in order to use it. This really makes the most sense, though, since you have to declare Servlets and Filters for your application regardless of whether you're using Guice Servlet or not.

Related

Spring Boot: Determining what autoconfiguration are applied to jersey?

Following the online docs for adding jersey to Sring boot, it appears I just need to include the following package
spring-boot-starter-jersey
Actually, it states that Spring Boot provides automatic configuration by including this package.
Where can I find out what exactly is happening?
If I don't add this package then what is NOT configured?
I tried searching for the package in google but got no specific explanation only saying that it automatically configures, but configures what?
I would like to know a little more of what is happening behind the scenes.
All of the auto-configuration code for all that Spring Boot supports is in the spring-boot-autoconfigure module. If you look through the packages, you will see a jersey package.
The "starter" modules generally do not have any code (of course unless it is a third-party module). How it works is that the code in the auto-configuration has some annotations that are #ConditionalOnXxx, where the condition be anything from a class being on the classpath. If this class is not available, then the auto-configuration will not take place. That's pretty much all adding the jersey starter module does: it adds the jersey dependencies so that the auto-configurer will applied.
Now what exactly is being auto-configured specifically for Jersey? Check out the source for the JerseyAutoConfiguration. Basically what you are going to see is your ResourceConfig being injected into the configurer. From that ResourceConfig, it creates Jersey's ServletContainer (which is the main entry point for Jersey.
Then, depending on our properties configuration, either a FilterRegistrationBean or a ServletRegistrationBean is created as a Spring bean, wrapping Jersey's ServletContainer. Jersey can be created as a Servlet or a Servlet Filter. Whichever one we configure we be used.
And that's it for the Jersey configuration. Spring Boot will get a servlet container (e.g. Tomcat, Jetty) from some other auto-configuration, and take the Filter/ServletRegistrationBean and add the Servlet/Filter to that servlet container.
Also, not really that important, but the auto-configuration also give us some Jackson configuration helpers. For example, instead of configuring our own ContextResolver, we can just configure an ObjectMapper Spring bean.
That's really all you get. It's nothing so spectacular that you couldn't just do it yourself without depending on the auto-configuration.
I would recommend learning a little more about how Spring Boot works to provide the automatic configuration in general.
A good reference is the spring boot reference guide. http://docs.spring.io/spring-boot/docs/1.5.3.RELEASE/reference/htmlsingle/#common-application-properties
You can look at the common application properties in appendix A to see what all spring allows you to configure out of the box.
The Reference guide also gives a high level of what "spring-boot-starter-jersey" if you search for it on the page.
They also have a few samples that you can go through and debug to follow along if that is a way for you to learn.
Hope that gives you a starting point for learning!

What is the equivalent of `transport-guarantee` when I register a Servlet in a BundleActivator without using web.xml?

I am running Servlets in an OSGI environment, specifically, I use Karaf with Pax Web / Jetty.
I was happily using the BundleActivator to instantiate servlets and register them with the HttpService. What I like about it is that it gives me a very straightforward way to handle dependency injection by wiring up a ServiceTracker.
However, for some things I can only find documentation about how to set them up via the classical web.xml configuration. Specifically, I miss an equivalent for the transport-guarantee instruction, i. e. a way to tell the HttpService that on certain URLs, it should insist on HTTPS and redirect the client if necessary.
Alternatively, if I can use the web.xml descriptor file as usual, but still get a convenient and simple way to wire up the servlet to my OSGi services, I would be fine with that.
Right now I'd say it's a web.xml only feature. Might want to open a new Feature Request. Regarding Injection of OSGi services in Servlets. If you combine your application with Pax CDI you are able to inject OSGi services by CDI means.
#WebServlet(urlPatterns = "/myServlet")
public class MyServlet extends HttpServlet {
#Inject
#OsgiService
private AnotherService service;
...

importing servlets from library in web.xml

I have included a library in my webapp. This library has its own web.xml. When I deploy the project on jetty, I find that the servlets from the library are not loaded. I have to manually add these servlets into the web.xml of my project. Is it possible to include these servlets in my project without me having to enter them all in my web.xml
If additional information regarding my problem is required, I would be happy to provide it.
you have to tell the servlet container that it has to initialize a sevlet. The usually way is to use the deployment descriptor (web.xml). Since JEE6 there is another option with annotations:
#WebServlet(urlPatterns="/forward")
public class ForwardServlet extends HttpServlet {
//code goes here...
}
But you'll have to try it, if it works with servlets inside a referenced library.

Dynamically add classes to Guice through reflection

Is it possible with Guice (and even in Java in general) to iterate over all classes in a particular package and add them to Guice?
The underlying problem: I'd like to be able to route all traffic to /admin/* to a single servlet which redirects accordingly. Then I'd like to be able to just add servlets to the same package and have them get picked up automatically. E.g. If I navigate to /admin/showCompanyDetails, I'd like that to redirect to a servlet called showCompanyDetails.java in the admin package.
Furthermore, I'd like this to work in such a way that all I have to do to add further admin functions is to drop a new class into the admin package. I.e. No factory methods to update and no containers to add to.
So far, the closest I've come is to have the redirect servlet create a Guice injector with a module that contains all the admin servlets. But as I said, I'd like to avoid having to update a Guice module.
Also, I'd like this to be possible in AppEngine.
And I want a pony.
There are some possibilities:
Use Servlet 3 #WebServlet annotations on your servlet classes, so they get picked up by a Servlet 3 web container. Then you can use Guice to inject dependencies, see here for an example.
Use guice-automatic-injection to bind your servlet classes in your classpath (they must contain their path similar to Servlet 3 via annotations or provide an accessor for it). Then you can create a Guice servlet module which retrieves all those servlets from Guice and registers them as servlets to their provided paths.
Both ways may be usable in AppEngine, but I haven't got experience with it.
Getting a pony is easy if you use just Object as its base class ;p

Using pure servlets (Java Servlet, no framework) in a project using the Spring framework?

We've got some Pure Servlets (pure Java classes following the Servlet API, no framework) that we'd like to include in a project that relies heavily on the Spring Framework.
What's the best way of including these servlets in the project, when all the new code we're writing is making heavy use of Spring 3 features?
your servlet container can run multiple servlets, spring is just one of them. why not just include your servlets in the web.xml and see if it works? it should work. spring is not that intrusive, yet (but obviously it already intruded the minds of many developers)
If you declare servlets in the web.xml, alongside the Spring front controller, it most certainly will work.
You just have to be careful when you declare which URLs map to the servlets. If you send "/*" to the Spring front controller, none of your requests will reach your other servlets. Be specific about what you need to send to each one.
As you might know, servlets cannot be configured as Spring beans. If your question is about colloborating with spring beans from a servlet, do refer this thread and also this
Spring provides a couple of classes to make this bridging easier.
ServletForwardingController
Spring Controller implementation that
forwards to a named servlet, i.e. the
"servlet-name" in web.xml rather than
a URL path mapping. A target servlet
doesn't even need a "servlet-mapping"
in web.xml in the first place: A
"servlet" declaration is sufficient.
Useful to invoke an existing servlet
via Spring's dispatching
infrastructure, for example to apply
Spring HandlerInterceptors to its
requests.
ServletWrappingController
Spring Controller implementation that
wraps a servlet instance which it
manages internally. Such a wrapped
servlet is not known outside of this
controller; its entire lifecycle is
covered here (in contrast to
ServletForwardingController).

Categories