I have the following ExceptionMapper:
#Provider
public class GenericExceptionMapper
implements ExceptionMapper<Exception> {
#Inject
private ExceptionDAO exceptionDAO;
#Override
public Response toResponse(Exception e) {
LOGGER.error(e.getMessage(), e);
return Response.status(INTERNAL_SERVER_ERROR)
.type(MediaType.TEXT_PLAIN)
.entity(e.getMessage())
.build();
}
The exceptionDAO is always null. I have a beans.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation=" http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee /beans_1_0.xsd"
></beans>
I have tried injecting alot of classes, but they always show as null.
Both the class being managed (ExceptionDAO) and the class injecting it need to be CDI-aware. In this case, this will probably involve marking both classes with #RequestScoped (or other CDI normal scope).
Do not get rid of the #Provider or other JAX-RS annotations; just add the CDI annotation.
Related
I can set default entity listener use persistence.xml.
How to set default entity listener use java code in spring-data-jpa?
I want to set the entity listener dynamically, hibernate.session_factory.interceptor
I did not find this in the hibernate or spring-data-jpa documentation.
hibernate docs
<entity-mappings xmlns="http://xmlns.jcp.org/xml/ns/persistence/orm"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence/orm
http://xmlns.jcp.org/xml/ns/persistence/orm_2_1.xsd"
version="2.1">
<persistence-unit-metadata>
<persistence-unit-defaults>
<entity-listeners>
<entity-listener
class="com.miya.system.listener.BackupDataListener">
<post-remove method-name="postRemove" />
</entity-listener>
</entity-listeners>
</persistence-unit-defaults>
</persistence-unit-metadata>
</entity-mappings>
You can customize the definition of LocalContainerEntityManagerFactoryBean to point it to your custom persistence.xml. The quick and dirty way in Spring Boot would be to create a BeanPostProcessor:
#Component
public class PersistenceXmlPostProcessor implements BeanPostProcessor {
#Override
public Object postProcessBeforeInitialization(Object bean, String beanName)
throws BeansException {
if (bean instanceof LocalContainerEntityManagerFactoryBean && runtimeConditionMet()) {
((LocalContainerEntityManagerFactoryBean) bean).setPersistenceXmlLocation(<your custom persistence.xml location>)
}
return bean;
}
}
As an alternative, you could customize the entity manager factory using BaseJpaAutoConfiguration:
#SpringBootApplication(exclude = HibernateJpaAutoConfiguration.class)
public class MyApplication {
...
}
#Configuration
public class CustomHibernateJpaConfiguration extends JpaBaseConfiguration {
...// copy most methods over from HibernateJpaConfiguration
#Override
public LocalContainerEntityManagerFactoryBean entityManagerFactory(EntityManagerFactoryBuilder factoryBuilder) {
var result = super.entityManagerFactory(factoryBuilder);
result.setPersistenceXmlLocation(...);
return result;
}
}
(an even cleaner solution could be to extend EntityManagerFactoryBuilder, but I hope you get the general idea).
I'm using Junit 5, Java bath that run under a webapp EE8 environment.
On the web app, I actually have a resources class that is employed as a producer:
#ApplicationScoped
public class Resources {
#Produces
public Logger produceLog(InjectionPoint injectionPoint) {
return LoggerFactory.getLogger(injectionPoint.getMember().getDeclaringClass().getName());
}
#Produces
#PersistenceContext(unitName = "primary")
private EntityManager entityManager;
}
Now I want to write some SE test, and I need to retrieve an alternative entity manager, something like:
public class MockResources {
#Alternative
#JobScoped
#Produces
public EntityManager getEntityManager() {
return Persistence.createEntityManagerFactory("primary").createEntityManager();
}
}
The issue is that I don't know how to retrieve this alternative entity , as beans.xml want a class (I tried with Hibernate SessionImpl but it doesn't work), neither #Stereotype looks good for my case.
<beans xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/beans_1_1.xsd"
bean-discovery-mode="all">
<alternatives>
<class>org.hibernate.internal.SessionImpl</class>
</alternatives>
</beans>
Any help ?
You should create an entire #Alternative Resources producer bean, as in
#Alternative
#ApplicationScoped
public class TestResources {
#Produces
public Logger produceLog(InjectionPoint injectionPoint) {
return LoggerFactory.getLogger(injectionPoint.getMember().getDeclaringClass().getName());
}
#Produces
private EntityManager getEntityManager() {
// create your new entitymanager here
return Persistence.createEntityManagerFactory("testunitname").createEntityManager();
}
}
Then define your test alternative class on test beans.xml as described on your question.
I'm studying how interceptors works in java. I'm using Netbeans IDE and just created a new project called Interceptors.
I created an annotation called "logged"
#Inherited
#InterceptorBinding
#Retention(RUNTIME)
#Target({METHOD, TYPE})
public #interface Logged { }
Then I created a class "LoggedInterceptor"
#Interceptor
public class LoggedInterceptor implements Serializable {
public LoggedInterceptor() {}
#AroundInvoke
public Object logMethodEntry(InvocationContext invocationContext) throws Exception
{
System.out.println("Entering method: "
+ invocationContext.getMethod().getName() + " in class "
+ invocationContext.getMethod().getDeclaringClass().getName());
return invocationContext.proceed();
}
}
Then I just created a class that make use of Logged annotation
public class SuperService
{
#Logged
public String deliverService(String uid)
{
return uid;
}
public static void main(String[] args)
{
SuperService ss = new SuperService();
System.out.println(ss.deliverService("sisi"));
}
}
Nothing happened. Later I added under src/main/resources/META-INF/ an xml file called beans.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee
http://xmlns.jcp.org/xml/ns/javaee/beans_1_1.xsd"
version="1.1"
bean-discovery-mode="all">
<interceptors>
<class>ascompany.interceptors.LoggedInterceptor</class>
</interceptors>
</beans>
But logMethodEntry method doesn't get called when I call deliverService method. Am I missing some other configuration file? Or just something else?
I already tried to add #Priority annotation to LoggedInterceptor but nothing changed...
EDIT:
I added logget annotation to LoggedInterceptor as #Luciano van der Veekens said but nothing changed
You forgot to annotate the LoggedInterceptor class with #Logged. This actually binds the annotation to the interceptor.
#Logged
#Interceptor
public class LoggedInterceptor implements Serializable {
}
They do the same in one of the Java EE 6 tutorials.
Also it looks like SuperService is just a regular class. An interceptor is a Java EE concept and only works for EJBs deployed on an application server.
I am trying to get Aspect working with Spring 3 and annotations.
#Aspect
public class AttributeAspect {
#Pointcut("#annotation(com.mak.selective.annotation.Attribute)")
public void process(){
System.out.println("Inside Process ....");
}
#Around("process()")
public void processAttribute(){
System.out.println("Inside Actual Aspect ..");
}
}
XML:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:util="http://www.springframework.org/schema/util"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-3.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd">
<aop:aspectj-autoproxy proxy-target-class="false" />
<context:component-scan base-package="com.mak.selective.annotation.*" />
<bean name="attribute" class="com.mak.selective.annotation.AttributeAspect"/>
</beans>
MY Test to test the Aspect:
#RunWith(SpringJUnit4ClassRunner.class)
#ContextConfiguration("/springcontext/*.xml")
public class AttributeTest {
#Attribute(tableName = "firstTable", columnName = "New Column")
private void getAttribute() {
System.out.println("Inside Attribute call...");
}
#Test
public void testAttributeAspect() {
getAttribute();
}
}
With this code i can only see "Inside Attribute call..." but nothing from Aspect.
Please guide.
Got this working by making a new Object (Component) and injected to the Junit test class.
Good to see that you got it working from XML, but you could have also done it from annotations.
The issue is that the #Aspect annotation is not a Spring stereotype, so the scanner is not registering the aspect as a Spring Bean. Just add either #Service or #Component above or below #Aspect and it will be registered.
Also, either directly name the bean (e.g., #Service("myNamedService")) or have it implement an interface (e.g., public class AttributeAspect implements IAspect {), as per standard Spring design.
You need to use real AspectJ if you want to intercept invocations of methods within the same bean form where it is invoked. (What you have done, should work if the method testAttributeAspect() is located in an other bean.)
How to do real AspectJ?
Using the AspectJ compiler and weaver enables use of the full AspectJ language, and is discussed in Section 7.8, “Using AspectJ with Spring applications”.
#See Spring Reference
A few things:
Firstly, when you do around advice you need to write the advice method like this:
#Around(...)
public void aroundAdviceMethod(ProceedingJoinPoint pjp) throws Throwable {
try {
System.out.println("before...");
pjp.proceed();
}
finally {
System.out.println("After...");
}
}
But also (and this at least applies when you're using proxies, not entirely sure in your case), the method you're putting advice on needs to be public (yours isn't), spring managed (via #Component or otherwise) and called external from the class so the proxy can take effect (also not the case in your example). So you need something like this:
#Component
public class SomeClass {
#Attribute
public void someMethodCall() {
System.out.println("In method call");
}
}
public class SomeUnitTest {
#Autowired SomeClass someClass;
#Test
public void testAspect() {
someClass.someMethodCall();
}
}
Is it possible to have the equivalent of <mvc:default-servlet-handler/> defined in an AnnotationConfig(Web)ApplicationContext? Right now I have:
#Configuration
#ImportResource("classpath:/mvc-resources.xml")
class AppConfig {
// Other configuration...
}
with just the following in my resources/mvc-resources.xml:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd">
<mvc:default-servlet-handler/>
</beans>
And it works as expected. Is it possible to do this without importing an XML file? It would be a nice way to cut down on some boilerplate.
If you are using Spring 3.1 with WebMvc, you can configure default servlet handling like this:
#Configuration
#EnableWebMvc
public class MvcConfig extends WebMvcConfigurerAdapter {
#Override
public void configureDefaultServletHandling(
DefaultServletHandlerConfigurer configurer) {
configurer.enable();
}
}
After digging a bit deeper, I found out that this is a known problem and is addressed by annotation features in the upcoming Spring 3.1.
I solved my problem with the following code:
#Configuration
#Import(FeatureConfig.class)
class AppConfig {
...
}
#FeatureConfiguration
class FeatureConfig {
#Feature
public MvcDefaultServletHandler defaultHandler() {
return new MvcDefaultServletHandler();
}
}
This does require using the milestone version of spring, though, but it seems to be the cleanest and preferred way of handling this.
I don't think you can do it out of the box, but you can probably copy what DefaultServletHandlerBeanDefinitionParser does: Create a Bean of type DefaultServletHttpRequestHandler and map it to the URL scheme /**.
I'd say your Bean should subclass DefaultServletHttpRequestHandler and do the mapping in a #PostConstruct method.
#Bean
public DefaultServletHttpRequestHandler defaultServletHttpRequestHandler() {
return new DefaultServletHttpRequestHandler();
}
#Bean
public SimpleUrlHandlerMapping simpleUrlHandlerMapping() {
Map<String, String> urlMap = new ManagedMap<String, String>();
urlMap.put("/**", defaultServletHandlerName);
SimpleUrlHandlerMapping hm = new SimpleUrlHandlerMapping();
hm.setUrlMap(urlMap);
return hm;
}