I have developed an SDK that uses a Resource in a rest package:
package com.example.some.package.rest;
...
#Path("/health")
public class HealthResource {
public HealthResource() {
// some code
}
#GET
#Path("/")
#Produces(MediaType.TEXT_HTML)
public Response getHealth() {
// some code to return health
}
}
Then I have another package with an Application implementation:
package com.example.different.package.rest;
...
public class HealthApplication extends Application {
public Set<Object> getSingletons() {
return Sets.<Object> newHashSet(new HealthResource());
}
}
However, this will not work for me. I have to use another wrapper class:
package com.example.different.package.rest;
...
#Path("")
public class WrapperHealthResource extends HealthResource {
public WrapperHealthResource() {
super();
}
}
If I use WrapperHealthResource in the HealthApplication instead of HealthResource, then it works fine.
I think it's pretty useless to have this extra class. How can I get rid of this complexity?
Firstly, I haven't been able to test this on Jersey 1.8 - I only have a 2.7 test harness around. But the API hasn't really changed in this area so you should be OK.
If you only need the Application class to enforce the Singleton of your HealthResource resource and nothing else, then I would just annotate the class with #Singleton and remove your Application class. That's the easiest.
I'm not able to reproduce your issue with 2.7, so this may be an issue with 1.8 (unlikely in this instance) or how you're registering your Application. If you want to post the rest of your code, I might be able to help.
Will
PS - if you're able, upgrade to 2.8.
Related
It seems to be a simple question but yet i couldn't find clear answer while searching documentation and forums. I'm migrating from xml to java-based config (Spring 5.1.9). Due to some legacy restrictions in xml config i need to create a bean from some side library's non public class:
SampleClass.class
package side.library
class SampleClass {
//... some code here
}
context.xml
...
<bean id = "sampleId" class "side.library.SampleClass">
...
And this works fine since Spring uses reflection inside and it creates bean without any problems at compile/runtime, but in java-based config usage of such class leads to an access error:
package my.configuration;
import side.library.SampleClass; // 'side.library.SampleClass' is not public in 'side.library'. Cannot be accessed from outside package
#Configuration
public class JavaConfiguration{
#Bean
public SampleClass sampleClass() {
return new SampleClass(); // same error text
}
}
So, what is the proper way to deal with this sutiation? Using reflection libs in #Configuration class to reach this class seems to be a bad idea.
just a workaround: create a wrapper class in the outer project in the same package and use this class in your configuration.
package com.legacy;
public class Wrapper {
private LegacyImpl legacyImpl;
public Wrapper()
this.legacyImpl = new LegacyImpl();
}
public void wrappedMethod() {
this.legacyImpl.wrappedMethod();
}
}
Im following a tutorial that has a external class InvoiceStorage i think, im very noob at this, but java cannot resolve that InvoiceStorage symbol, so i think i need a dependency that is not shown in the tutorial
tutorial link:
https://semaphoreci.com/community/tutorials/stubbing-and-mocking-with-mockito-2-and-junit
package com.mokitoTutorial.app;
import com.clusterra.email.sender.EmailSender;
public class LateInvoiceNotifier {
private final EmailSender emailSender;
private final InvoiceStorage invoiceStorage;
public LateInvoiceNotifier(final EmailSender emailSender, final InvoiceStorage invoiceStorage){
this.emailSender = emailSender;
this.invoiceStorage = invoiceStorage;
}
public void notifyIfLate(Customer customer)
{
if(invoiceStorage.hasOutstandingInvoice(customer)){
emailSender.sendEmail(customer);
}
}
}
In this article, the author has just provided an example about how to use mockito. You can see the below from the above article.
In a real system, the InvoiceStorage class is actually a web service
that connects with an external legacy CRM system which is slow. A unit
test could never make use of such as web service.
The author is referring to a class called InvoiceStorage, it is for example. There is no dependency. You can follow the article and you can create your own class to test.
I'm new to specifying resource routes in Java, and I'm having issues specifying the route. So far I have one Class which simply extends Application, and one class that reacts to input. What are the routing requirements for these classes? My code below does not work and im trying to figure out why. I've tried to find sources for these, but haven't had much luck.
Can I just use a / for the ApplicationPath? All this class does is extend Application so it can find routes.
Example:
package com.sentiment360.helloworld;
import javax.ws.rs.ApplicationPath;
import javax.ws.rs.core.Application;
/**
* JAXActivator is an arbitrary name, what is important is that javax.ws.rs.core.Application is extended
* and the #ApplicationPath annotation is used with a "rest" path. Without this the rest routes linked to
* from index.html would not be found.
*/
#ApplicationPath("/")
public class JAXActivator extends Application {
}
Does each class need to have a declared #Path (or can they all be #Stateless)?
#Path("/helloservice")
public class HelloService {
private static Logger _logger;
public HelloService(){
_logger = Logger.getLogger(HelloService.class.getName());
}
private Connection conn() throws SQLException {...}
}
The short version for #1 is yes.
BUT: behavior is implementation dependent. See https://stackoverflow.com/a/16747253/1063501 for a thorough explanation.
As for #2, yes, you generally need to specify a #Path for every endpoint you want. The fact that it is #Stateless is irrelevant as you'll need a way to address it.
I've been looking all over Google to find some useful information on how to use Guice/Spring DI in Play Framework 2.1
What I want to do is to Inject several Services in some DAO's and vice versa.
Just need some clarification on this - With play 2.1, do you have to use an # annotation within the routes file for DI?
I've looked at this guide here - https://github.com/playframework/Play20/blob/master/documentation/manual/javaGuide/main/inject/JavaInjection.md
and applied the following steps creating a Global class in app and adding the GUICE dependencies in Build.scala but keep on getting a null pointer exception when invoking on the injected object.
Has anyone been able to get DI working in Play 2.1 using Guice? I've seen examples across the internet but they all seem to be using DI within the controller.
I noticed you are using Java. Here is how I got it to work for injecting into a controller.
First, I created the following 4 classes :
MyController:
package controllers;
import play.mvc.*;
import javax.inject.Inject;
public class MyController extends Controller {
#Inject
private MyInterface myInterface;
public Result someActionMethodThatUsesMyInterface(){
return ok(myInterface.foo());
}
}
MyInterface:
package models;
public interface MyInterface {
String foo();
}
MyImplementation2Inject:
package models;
public class MyImplementation2Inject implements MyInterface {
public String foo() {
return "Hi mom!";
}
}
MyComponentModule:
package modules;
import com.google.inject.AbstractModule;
import models.MyInterface;
import models.MyImplementation2Inject;
public class ComponentModule extends AbstractModule {
#Override
protected void configure() {
bind(MyInterface.class).
to(MyImplementation2Inject.class);
}
}
Now the final part, that took me a silly long time to figure out, was to register the module. You do this by adding the following line to the end of the application.conf file, which is located in the conf directory:
play.modules.enabled += "modules.MyComponentModule"
I hope this was helpful to you. :)
I use cake pattern and my own version of Global overriding getControllerInstance
https://github.com/benjaminparker/play-inject
Cheers
Ben
Sorry, this is a late response, but here's our example
https://github.com/typesafehub/play-guice
Have you tried using some different approach to DI than Guice?
We also tried implementing a project with Guice or Spring but ended in registering our dependencies in objects that implement trait such as:
trait Registry {
def userDao: UserDao
...
}
object Registry {
var current: Registry = _
}
object Environnment {
object Dev extends Registry {
val userDao = ...
//implement your environment for develpment here
}
object Test extends Registry {
val userDao = ...
//implement your ennviroment for tests here e.g. with mock objects
}
}
Another good approach wich might fit for you is the cake pattern (just google for it).
I think I have misunderstood something about the Play 2 framework.
In my Application Controller I fetch a Company object from the DB
and I would like to make some operations on it in my view.
companyView.scala.html:
#(company: Company)
#main("Welcome to Play 2.0") {
<h1>#{company.name}</h1>
}
Application Controller:
package controllers;
import models.Company;
import play.*;
import play.mvc.*;
import views.html.*;
public class Application extends Controller {
public static Result company(String rest) {
Company company =
Company.find.where().ilike("restfulIdentifier.identifier", rest).findUnique();
return ok(companyView.render(company));
}
}
But return ok(companyView.render(company)); results in compilation error since companyView.render wants a string.
If I look at the forms sample application:
/**
* Handle the form submission.
*/
public static Result submit() {
Form<Contact> filledForm = contactForm.bindFromRequest();
if(filledForm.hasErrors()) {
return badRequest(form.render(filledForm));
} else {
Contact created = filledForm.get();
return ok(summary.render(created));
}
}
There is no problem with rendering an object. I guess that the solution is fairly simple and
that I have missed some crucial part of the documentation. Please explain this to me!
My steps in this case would be as follows:
Change the scala template, we hve to tell the scala templates the our Company belongs to the model class: (but also change to #company.name as suggested by Jordan.
#(company: models.Company)
#main("Welcome to Play 2.0") {
<h1>#company.name</h1>
}
run command play clean
Then run play debug ~run
By executing play debug ~run you will trigger to compile the the play application on each SAVE of one of your project files.
NOTE: The Play templates are basically functions. These functions needs to be compiled and everything used in these functions needs to be declared before use. Just as in regular Java development.
The fact that the your render object wants a string could be the result of:
#(company: Company) could not be resolved to the model Company.
The last compilation had a #(company: String)
Good luck!
I don't know if this will fix your problem or not but it's worth a try. Try removing changing:
#{company.name}
to:
#company.name