#Path Annotation requirements? - java

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.

Related

SpringBoot #Autowire why does this example work?

I have created this class:
import org.springframework.stereotype.Component;
...
#Component("notTheNameTestMe") //shouldnt this only work with testMe ?
public class TestMe {
public void showMsg() {
System.out.println("Autowiring works");
}
}
And I'm using it this way in a second class (or better: controller):
import com.example.TestMe; //shouldnt this be not necessary with autowire? But getting error else...
...
#Autowired
private TestMe testMe;
...
this.testMe.showMsg();
But this works perfectly (so maybe Im not really using autowire here?), it even works if I rename the whole TestMe class to TestMeSomething (if I adjust the import in the second class)
I dont really understand what #Autowired does. I thought it just scans for SpringBoot Components (which are named by the string in #Component() and when it finds a match it Injects the dependancy. But in my example the match is impossible and I still can see the message "Autowiring works" in the console. This shouldnt be like this if I would really use autowire here or? What am I understanding in a wrong way? What is the difference to using new TestMe() then? I have the dependancy already with the import or? So not a real dependancy injection, or?
Spring is not operating on the name in the #Component annotation. Rather it's using the name of the class. It's simply finding a class named TestMe because that's the type of the variable you've annotated with #Autowired.

Bean interface and Bean implementation in different projects

Is it possible to have a bean interface in a project and the implementation of that bean in another project that includes the previous project as a dependency?
I have the following interface:
package com.proj1.util;
import .....;
public interface Notification {
addNotification();
addError();
}
In the same project (i.e. Proj1) I have also the following class:
package com.proj1.util.exception;
import .....;
public class ExceptionHandler extends RuntimeException ... {
private String errorMessage;
#Override
public void handle() {
Util.getBeanInstance(Notification.class).addError(errorMessage);
}
}
Now in the second project I have the actual implementation of Notification that is as follows:
package com.proj2.beans;
#Named
#ConversationScoped
public class NotificationBean implements Notification, Serializable {
private static final long serialVersionUID = 1L;
...
}
This situation leads to an exception in Tomcat with the message "WebBeans context with scope type annotation #ConversationScoped does not exist within current thread"
My proposal was to add a Factory that produces my NotificationBean but it doesn't seem to change much.
package com.proj2.beans.cdi;
import javax.enterprise.inject.New;
import javax.enterprise.inject.Produces;
import com.proj1.util.Notification;
public class NotificationBeanFactory {
#Produces
public Notification create(#New NotificationBean notificationBean) {
return notificationBean;
}
}
The question is how can I use a bean in a project in which I have only it's interface while the bean implementation is in another project. Is it possible?
The exception suggests there is no running conversation so I would start by determining when do you attempt to use #ConversationScoped bean and from which class.
Your code pieces indicate that ExceptionHandler class calls a magical formula which we do not know anything else about:
Util.getBeanInstance(Notification.class).add(...);
Trying to use this when there is no active conversation might lead to the exception you see. Therefore you could #Inject ExceptionHandler into NotificationBean so that you only ever use it while there is active conversation.
As for the Weld question regarding interface and impl in different projects; it is possible. in your proj2 Weld will simply identify a bean NotificationBean and amongst it's types there will also be Notification hence you can then #Inject Notification.
It might not work the other way round though - in proj1 you cannot #Inject Notification because proj1 itself does not have any bean which would implement that interface.

Java: Can you expose 3rd party interface from your own class

We’re using log4j2 to do logging throughout our application and now I want to add some additional functions to the LogManager…at the same time, I hoped it would be possible to hide the “implementation details” of the LogManager for the rest of the application, so that instead of importing the log4j2 Logger everywhere, I can expose my own interface or class, from my own proprietary LogManager (that way, it would be possible to refactor or replace the way I store log messages without affecting the entire application).
I can create my own LogManager, called LM, easily like this:
package com.xxx.yyy.logging;
import org.apache.logging.log4j.LogManager;
public class LM extends LogManager {
…add own methods here…
}
But when I call:
LM.getLogger(Application.class)
It returns an object of type org.apache.logging.log4j.Logger – is there an easy way to “wrap and expose” this interface via my own package, so that the rest of the application don’t have to be concerned with log4j?
I’ve tried something like:
package com.xxx.yyy.logging;
import org.apache.logging.log4j.Logger;
import org.apache.logging.log4j.core.LoggerContext;
import org.apache.logging.log4j.message.MessageFactory;
public class LMlogger extends org.apache.logging.log4j.core.Logger implements Logger {
protected LMlogger(LoggerContext context, String name,
MessageFactory messageFactory) {
super(context, name, messageFactory);
// TODO Auto-generated constructor stub
}
};
…in order to implement the class returned as well as the expected interface, but still I can’t “down-cast” the returned Logger-object to my own LMlogger (which makes sense, as my class is the sub-class). But is there another way to keep the log4j2 implemenation details in one place only, without having to wrap each and every method of the Logger-class?
You can use the tool that log4j2 provides to generate custom Logger wrappers.
This tool was intended to add convenience methods for custom log levels or hide existing log levels, but you can use it for any purpose.
It also hides the LogManager from the client code (your app), and the generated code is in whatever package you specify, so client code won't be aware it is using log4j2.
You may need to regenerate the wrapper when you upgrade log4j2 after it had API changes (which is rare, but there will be additional API in 2.6).
Look at the following way:
Create a same-name Class org.apache.logging.log4j.LogManager in your project, and copy the source code of the original org.apache.logging.log4j.LogManager in log4j lib. Then edit the code and add what you want.
Logger or other class in the same way.
But you must make sure that your project must be loaded before the log4j lib.

How to access package via Package.getPackage(...)?

In my current project I would like to store some configuration data in a package annotation and to access it by some CDI producers. If the annotation is not found in the current package the producers will search for it upward in the package hierarchy.
So far so good. Unfortunately it seems so that I can access an existing package via Package.getPackage("my.package") only after the first access to one of its classes or interfaces.
The following example illustrates this behaviour:
Class in package a.b
package a.b;
public class ClassInMitte {
}
Example programm to access the package oben.mitte
package other;
public class Refl {
public static void main(String[] args)
{
Package viaName = Package.getPackage("a.b");
System.out.println(viaName.getName());
System.out.println(viaName.hashCode());
}
}
Running Refl results in a NullPointerException. But if I add new ClassInMitte() as first statement I can access the package information. Somehow I must access the content of a package before I can access the package information itself. This makes sense since otherwise the classloaders must scan the whole classpath while starting.
But netherless is there an easy way to access package information without accessing the content of the package before? I know I could use frameworks like reflections but a 'lightweight' solution would be my prefered solution.
Package.getPackage only returns packages that are already known to the current class loader, and the only way to do that is by loading a class from that package. It's basically a wrapper for ClassLoader.getPackage.

Play Framework Dependency Injection

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).

Categories

Resources