Apache Tiles 3.0 - Locally Save and Reference DTD - tiles

We're using Apache Tiles 3.0.
In our Apache Tiles-Def file, we occasionally have problems with this DTD reference, maybe because the site is unreliable. There are I/O errors "Reading Definitions" occasionally:
<!DOCTYPE tiles-definitions PUBLIC "-//Apache Software Foundation//DTD Tiles Configuration 3.0//EN"
"http://tiles.apache.org/dtds/tiles-config_3_0.dtd">
The idea came up to save the DTD in the project. We dropped the DTD into /WEB-INF/classes, but it can't be found:
1) just "tiles-config_3_0.dtd":
Error: C:\Eclipse\LunaSR2\tiles-config_3_0.dtd not found
2) "/WEB-INF/classes/tiles-config_3_0.dtd":
java.io.FileNotFoundException: \WEB-INF\classes\tiles-config_3_0.dtd (The system cannot find the path specified)

1 ) In WEB-INF folder need to place the tiles-config_3_0.dtd
WEB-INF\tiles-config_3_0.dtd
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE tiles-definitions PUBLIC
"-//Apache Software Foundation//DTD Tiles Configuration 3.0//EN"
"http://tiles.apache.org/dtds/tiles-config_3_0.dtd">
2 ) Add the below mentioned dependencies in pom.xml
<dependency>
<groupId>org.apache.tiles</groupId>
<artifactId>tiles-core</artifactId>
<version>3.0.8</version>
</dependency>
<dependency>
<groupId>org.apache.tiles</groupId>
<artifactId>tiles-api</artifactId>
<version>3.0.8</version>
</dependency>
<dependency>
<groupId>org.apache.tiles</groupId>
<artifactId>tiles-servlet</artifactId>
<version>3.0.8</version>
</dependency>
<dependency>
<groupId>org.apache.tiles</groupId>
<artifactId>tiles-template</artifactId>
<version>3.0.8</version>
</dependency>
<dependency>
<groupId>org.apache.tiles</groupId>
<artifactId>tiles-el</artifactId>
<version>3.0.8</version>
</dependency>
</dependency>
<dependency>
<groupId>org.apache.tiles</groupId>
<artifactId>tiles-master</artifactId>
<version>6</version> or
<version>7</version>
</dependency>
3 ) Provide the concern classes in Dispatch-servlet.xml
<bean id="viewResolver"
class="org.springframework.web.servlet.view.UrlBasedViewResolver">
<property name="viewClass">
<value> org.springframework.web.servlet.view.tiles3.TilesView</value>
</property>
</bean>
<bean id="tilesConfigurerId"
class="org.springframework.web.servlet.view.tiles3.TilesConfigurer">
<property name="definitions">
<list>
<value>/WEB-INF/tiles-config_3_0.dtd</value>
</list>
</property>
</bean>

Related

Simple Spring project - HTTP 404

When I run the program on a tomcat server, it shows me the index page but whenever I'm trying to request an URL matching the #RequestMapping annotation, I'm getting a 404 error.
There is also no exception thrown. I put a System.out.print inside the controller's method to see if it's executed on request but there is nothing printed on the console.
It may be a configuration problem in the IDE, but despite days of searching a solution, I didn't find a way to solve it. I hope someone will help me for this issue. I'm using intellij.
Project
WEB-INF/web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app 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/web-app_4_0.xsd"
version="4.0">
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/dispatcher-servlet.xml</param-value>
</context-param>
<servlet>
<servlet-name>dispatcher</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>dispatcher</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
</web-app>
WEB-INF/dispatcher-servlet.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:context="http://www.springframework.org/schema/context"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx.xsd">
<!-- Add support for component scanning -->
<context:component-scan base-package="com.luv2code.springdemo" />
<!-- Add support for conversion, formatting and validation support -->
<mvc:annotation-driven/>
<!-- Define Spring MVC view resolver-->
<bean
class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/view/" />
<property name="suffix" value=".jsp" />
</bean>
<!-- Step 1: Define Database DataSource / connection pool -->
<bean id="myDataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"
destroy-method="close">
<property name="driverClass" value="com.mysql.cj.jdbc.Driver" />
<property name="jdbcUrl" value="jdbc:mysql://localhost:3306/web_customer_tracker?useSSL=false&serverTimezone=UTC" />
<property name="user" value="springstudent" />
<property name="password" value="springstudent" />
<!-- these are connection pool properties for C3P0 -->
<property name="minPoolSize" value="5" />
<property name="maxPoolSize" value="20" />
<property name="maxIdleTime" value="30000" />
</bean>
<!-- Step 2: Setup Hibernate session factory -->
<bean id="sessionFactory"
class="org.springframework.orm.hibernate5.LocalSessionFactoryBean">
<property name="dataSource" ref="myDataSource" />
<property name="packagesToScan" value="com.luv2code.springdemo.entity" />
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.MySQL5Dialect</prop>
<prop key="hibernate.show_sql">true</prop>
</props>
</property>
</bean>
<!-- Step 3: Setup Hibernate transaction manager -->
<bean id="myTransactionManager"
class="org.springframework.orm.hibernate5.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory"/>
</bean>
<!-- Step 4: Enable configuration of transactional behavior based on annotations -->
<tx:annotation-driven transaction-manager="myTransactionManager" />
</beans>
CustomerController
#Controller
public class CustomerController {
#RequestMapping("/list")
public String listCustomers(){
System.out.println("ici");
return "list-customers";
}
}
pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<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>groupId</groupId>
<artifactId>untitled1</artifactId>
<version>1.0-SNAPSHOT</version>
<properties>
<springframework.version>5.1.5.RELEASE</springframework.version>
<hibernate.version>5.4.1.Final</hibernate.version>
<mysql.connector.version>5.1.47</mysql.connector.version>
<c3po.version>0.9.5.2</c3po.version>
<maven.compiler.source>11</maven.compiler.source>
<maven.compiler.target>11</maven.compiler.target>
</properties>
<dependencies>
<!-- Spring -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>${springframework.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-tx</artifactId>
<version>${springframework.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-orm</artifactId>
<version>${springframework.version}</version>
</dependency>
<!-- Hibernate -->
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-core</artifactId>
<version>${hibernate.version}</version>
</dependency>
<!-- MySQL -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>${mysql.connector.version}</version>
</dependency>
<!-- C3PO -->
<dependency>
<groupId>com.mchange</groupId>
<artifactId>c3p0</artifactId>
<version>0.9.5.2</version>
</dependency>
<!-- Servlet+JSP+JSTL -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.1.0</version>
</dependency>
<dependency>
<groupId>javax.servlet.jsp</groupId>
<artifactId>javax.servlet.jsp-api</artifactId>
<version>2.3.1</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
<version>1.2</version>
</dependency>
<!-- to compensate for java 9+ not including jaxb -->
<dependency>
<groupId>javax.xml.bind</groupId>
<artifactId>jaxb-api</artifactId>
<version>2.3.0</version>
</dependency>
</dependencies>
<build>
<finalName>spring-web-customer-tracker</finalName>
<plugins>
<!-- Builds a Web Application Archive (WAR) file from the project output
and its dependencies. -->
<plugin>
<!-- Add Maven coordinates (GAV) for: maven-war-plugin -->
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>3.2.0</version>
</plugin>
</plugins>
</build>
</project>
There are multiple issues with the attached project like the duplicate libraries from lib directory and from Maven and the exploded web artifact not including any of the libraries. I'd recommend deleting .idea and lib directories from the project. Then reimport it from pom.xml. You should get the dependencies and the artifact configured automatically.
The main issue right now is that artifact is not deploying any jars from the dependencies, therefore none of the Spring code works and you just get the basic JSP functionality.
There is also a problem with JDBC configuration, bit it's not related to IntelliJ IDEA and you may want to submit a new question if you can't figure it out.

Configure hibernate 3 in Jboss7

I'm trying to set up a Spring MVC + Hibernate WAR for deployment to Jboss 7.1.1 Final. My application using Hibernate 3.6.1 & So far my understanding is that Hibernate 4 is packaged with the AS and is the default persistence provider. I am not using persistent.xml file configuration.
I have followed all steps required to setup Hibernate 3 in JBoss.
Go to the AS installation and change into the modules/org folder.
Created folder for slot 3 to hold Hibernate 3
Copied the Hibernate3 jars into this new AS/modules/org/hibernate/3 folder
(hibernate3-core.jar, hibernate3-commons-annotations.jar, hibernate3-entitymanager.jar, dom4j.jar, slf4j.jar, slf4j-api.jar, commons-collections.jar, antlr.jar, slf4j-api.jar, commons-collections.jar, antlr.jar and any other jar needed for Hibernate 3)
Created the AS/modules/org/hibernate/3/module.xml file with contents:
<?xml version="1.0" encoding="UTF-8"?>
<module xmlns="urn:jboss:module:1.0" name="org.hibernate" slot="3">
<resources>
<resource-root path="hibernate3-core.jar"/>
<resource-root path="hibernate3-commons-annotations.jar"/>
<resource-root path="hibernate3-entitymanager.jar"/>
<resource-root path="javassist-3.12.0.GA.jar"/>
<resource-root path="antlr-2.7.6.jar"/>
<resource-root path="commons-collections-3.1.jar"/>
<resource-root path="dom4j-1.6.1.jar"/>
<!-- Insert other Hibernate 3 jars to be used here -->
</resources>
<dependencies>
<module name="org.jboss.as.jpa.hibernate" slot="3"/>
<module name="asm.asm"/>
<module name="javax.api"/>
<module name="javax.persistence.api"/>
<module name="javax.transaction.api"/>
<module name="javax.validation.api"/>
<module name="org.apache.ant"/>
<module name="org.infinispan"/>
<module name="org.javassist"/>
<module name="org.slf4j"/>
</dependencies>
</module>
My pom.xml(part):
<!-- Hibernate dependencies -->
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-core</artifactId>
<version>3.6.6.Final</version>
<exclusions>
<exclusion>
<groupId>xml-apis</groupId>
<artifactId>xml-apis</artifactId>
</exclusion>
</exclusions>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-annotations</artifactId>
<version>3.5.6-Final</version>
</dependency>
<dependency>
<groupId>javax.persistence</groupId>
<artifactId>persistence-api</artifactId>
<version>1.0.2</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-validator</artifactId>
<version>3.0.0.ga</version>
</dependency>
<dependency>
<groupId>org.hibernate.common</groupId>
<artifactId>hibernate-commons-annotations</artifactId>
<version>4.0.5.Final</version>
</dependency>
My hibernate-context.xml(Part)
<jpa:repositories base-package="com.gea.dvr.repository" />
<bean id="sessionFactory" class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean"
p:dataSource-ref="dataSource"
p:configLocation="${hibernate.config}"
p:packagesToScan="com.iana.dver"/>
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method="close"
p:driverClass="${app.jdbc.driverClassName}"
p:jdbcUrl="${app.jdbc.url}"
p:user="${app.jdbc.username}"
p:password="${app.jdbc.password}"
p:idleConnectionTestPeriod="30"
p:maxPoolSize="100"
p:maxStatements="50"
p:minPoolSize="10"
p:maxIdleTime="60" />
<!-- Declare a transaction manager-->
<bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager"
p:sessionFactory-ref="sessionFactory" />
<!-- Specify our ORM vendor -->
<bean id="hibernateVendor" class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter"
p:showSql="false"/>
My hibernate.cfg.xml
<hibernate-configuration>
<session-factory name="sessionFactory">
<!-- We're using MySQL database so the dialect needs to MySQL as well-->
<property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>
<!-- Enable this to see the SQL statements in the logs-->
<property name="show_sql">false</property>
<!-- This will drop our existing database and re-create a new one.
Existing data will be deleted! -->
<!-- <property name="hbm2ddl.auto">update</property>-->
<mapping class="com.gea.dvr.domain.DvrUserType"/>
<mapping class="com.gea.dvr.domain.DvrUsers"/>
<mapping class="com.gea.dvr.domain.DvrConfig"/>
<mapping class="com.gea.dvr.domain.DvrDetail"/>
<mapping class="com.gea.dvr.domain.DvrFiles"/>
<mapping class="com.gea.dvr.domain.DvrNotif"/>
<mapping class="com.gea.dvr.domain.UserLogin"/>
</session-factory>
</hibernate-configuration>
I have provided all required java still I am still getting following exception,
Can anyone help me to setup hibernate 3 related changes in JBoss?
11:03:14,597 ERROR [org.springframework.web.context.ContextLoader] (MSC service thread 1-3) Context initialization failed: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'hibernateVendor' defined in ServletContext resource [/WEB-INF/hibernate-context.xml]: Instantiation of bean failed; nested exception is org.springframework.beans.BeanInstantiationException: Could not instantiate bean class [org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter]: Constructor threw exception; nested exception is java.lang.NoClassDefFoundError: org/hibernate/ejb/HibernatePersistence
Since you get a java.lang.NoClassDefFoundError (and not a ClassNotFoundException), it's probably some sort of classloading issue.
try adding hibernate-entitymanager dependency that will solve your problem.
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-entitymanager</artifactId>
<version>${hibernate.version}</version>
<exclusions>
<exclusion>
<groupId>cglib</groupId>
<artifactId>cglib</artifactId>
</exclusion>
<exclusion>
<groupId>dom4j</groupId>
<artifactId>dom4j</artifactId>
</exclusion>
</exclusions>
</dependency>

Struts 2 Annotation With Interceptors not Working

I have been trying to implement Interceptors in my application each and everything works fine till the time I don't include interceptor Annotation in my action. But, when I just add the InterceptoRef tag in my action like the code below:
#InterceptorRefs({
#InterceptorRef("mylogging")
})
public class LoginAction implements ModelDriven{
It starts giving me exception
SEVERE: Exception starting filter struts2
Unable to load configuration. - [unknown location]
at org.apache.struts2.dispatcher.Dispatcher.init(Dispatcher.java:431)
at org.apache.struts2.dispatcher.ng.InitOperations.initDispatcher(InitOperations.java:69)
at org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter.init(StrutsPrepareAndExecuteFilter.java:51)
at org.apache.catalina.core.ApplicationFilterConfig.initFilter(ApplicationFilterConfig.java:281)
at org.apache.catalina.core.ApplicationFilterConfig.getFilter(ApplicationFilterConfig.java:262)
at org.apache.catalina.core.ApplicationFilterConfig.<init>(ApplicationFilterConfig.java:107)
at org.apache.catalina.core.StandardContext.filterStart(StandardContext.java:4746)
at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5399)
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150)
at org.apache.catalina.core.ContainerBase.addChildInternal(ContainerBase.java:901)
at org.apache.catalina.core.ContainerBase.addChild(ContainerBase.java:877)
at org.apache.catalina.core.StandardHost.addChild(StandardHost.java:633)
at org.apache.catalina.startup.HostConfig.deployWAR(HostConfig.java:977)
at org.apache.catalina.startup.HostConfig$DeployWar.run(HostConfig.java:1654)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:441)
at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:303)
at java.util.concurrent.FutureTask.run(FutureTask.java:138)
at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
at java.lang.Thread.run(Thread.java:662)
Caused by: Unable to load configuration. - [unknown location]
at com.opensymphony.xwork2.config.ConfigurationManager.getConfiguration(ConfigurationManager.java:58)
at org.apache.struts2.dispatcher.Dispatcher.init_PreloadConfiguration(Dispatcher.java:374)
at org.apache.struts2.dispatcher.Dispatcher.init(Dispatcher.java:418)
... 19 more
Caused by: Unable to find interceptor class referenced by ref-name mylogging - [unknown location]
I am using Struts 2 with Struts2-convention-plugin , Hibernate, Spring and using Maven for dependency management.
I have following dependencies which I have defined in Maven's POM file:
<dependency>
<groupId>org.apache.struts</groupId>
<artifactId>struts2-core</artifactId>
<version>2.1.8.1</version>
</dependency>
<!-- Struts 2 + Spring plugins -->
<dependency>
<groupId>org.apache.struts</groupId>
<artifactId>struts2-spring-plugin</artifactId>
<version>2.1.8.1</version>
</dependency>
<!-- MySQL database driver -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.9</version>
</dependency>
<!-- Spring framework -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring</artifactId>
<version>2.5.6</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>2.5.6</version>
</dependency>
<!-- Hibernate core -->
<dependency>
<groupId>asm</groupId>
<artifactId>asm-all</artifactId>
<version>3.3</version>
</dependency>
<dependency>
<groupId>asm</groupId>
<artifactId>asm</artifactId>
<version>3.3</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-core</artifactId>
<version>3.6.7.Final</version>
</dependency>
<dependency>
<groupId>org.apache.struts</groupId>
<artifactId>struts2-convention-plugin</artifactId>
<version>2.1.8.1</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.0.1</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.15</version>
</dependency>
I have placed Struts.xml in the src root. So as far as I think there must be something missing in configuration.
Struts.xml file configuration:
<struts>
<constant name="struts.devMode" value="false" />
<constant name="struts.convention.package.locators.basePackage" value="com.abc.lab"/>
<constant name="struts.convention.exclude.packages" value="org.apache.struts.*,org.apache.struts2.*,org.springframework.web.struts.*,org.springframework.web.struts2.*,org.hibernate.*,WarFileName.*"/>
<constant name="struts.convention.action.checkImplementsAction" value="false"/>
<constant name="struts.convention.package.locators" value="action,actions,struts,struts2"/>
<package name="default" extends="struts-default" namespace="/">
<interceptors>
<interceptor name="mylogging"
class="com.abc.lab.interceptor.LoggingInterceptor">
</interceptor>
<interceptor-stack name="loggingStack">
<interceptor-ref name="mylogging" />
<interceptor-ref name="defaultStack" />
</interceptor-stack>
</interceptors>
</package>
</struts>
If you get errors like "Unable to find interceptor class referenced by ref-name XYZ". This means that the package where Convention is placing your actions, does not extend the package where the interceptor is defined. To fix this problem either 1)Use #ParentPackage annotation(or struts.convention.default.parent.package) passing the name of the package that defines the interceptor, or 2) Create a package in XML that extends the package that defines the interceptor, and use #ParentPackage(or struts.convention.default.parent.package) to point to it.

How to configure AspectJ with Load Time Weaving without Interface

On my project, I currently use AspectJ (not just Spring AOP due to some limitation) with the weaving at the Compile Time. In order to speed up the development on Eclipse, I want to do the weaving at the Load Time. I succeed to do that but with one major constraint: using an interface for my service that contained some transactional methods. If I declare the service with its implementation instead of its interface, in the caller class, there is no weaving and so no transaction supported.
So if it is supported by AspectJ, how to configure AspectJ with Load Time Weaving without Interface ?
I created a little project that reproduce the issue:
The following test fail.
The following test succeed if :
the injected service is declared with its interface instead of its implementation (i.e. replace "#Inject MyServiceImpl service" by "#Inject MyService service"), the test succeed.
the weaving is executed during the compilation (the configuration, POM & Spring application context, is obviously different in this case). But my goal is to do the weaving at the Load-Time to avoid a weaving phase every time I save a Java file.
Spring AOP (tx:annotation-driven mode="proxy"), that is a proxy-based solution, is used instead of AspectJ. But in this case, we encountered the self-invocation issue, i.e. a method within the target object calling some other method of the target object, won’t lead to an actual transaction at runtime even if the invoked method is marked with #Transactional.
aspectj-ltw/src/test/java/mycompany/aspectj_ltw/MyServiceImplTest.java
package mycompany.aspectj_ltw;
import static junit.framework.Assert.assertTrue;
import javax.inject.Inject;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
#RunWith(SpringJUnit4ClassRunner.class)
#ContextConfiguration(locations = { "classpath:/META-INF/spring/applicationContext.xml" })
public class MyServiceImplTest {
#Inject
MyServiceImpl service;
#Test
public void shouldBeExecutedInTransaction() {
assertTrue(this.service.isExecutedInTransaction());
}
}
aspectj-ltw/src/main/java/mycompany/aspectj_ltw/MyService.java
package mycompany.aspectj_ltw;
public interface MyService {
boolean isExecutedInTransaction();
}
aspectj-ltw/src/main/java/mycompany/aspectj_ltw/MyServiceImpl.java
package mycompany.aspectj_ltw;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.support.TransactionSynchronizationManager;
#Service
public class MyServiceImpl implements MyService {
#Transactional
public boolean isExecutedInTransaction() {
return TransactionSynchronizationManager.isActualTransactionActive();
}
}
aspectj-ltw/src/test/resources/META-INF/applicationContext.xml
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:aop="http://www.springframework.org/schema/aop" xmlns:context="http://www.springframework.org/schema/context"
xmlns:jee="http://www.springframework.org/schema/jee" xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-3.0.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd">
<context:component-scan base-package="mycompany.aspectj_ltw" />
<context:load-time-weaver aspectj-weaving="on" />
<aop:config proxy-target-class="true"/>
<aop:aspectj-autoproxy proxy-target-class="true"/>
<tx:annotation-driven mode="aspectj"
transaction-manager="transactionManager" proxy-target-class="true" />
<bean class="org.apache.commons.dbcp.BasicDataSource"
destroy-method="close" id="dataSource">
<property name="driverClassName" value="org.h2.Driver" />
<property name="url" value="jdbc:h2:mem:mydb" />
<property name="username" value="sa" />
<property name="password" value="" />
</bean>
<bean class="org.springframework.jdbc.datasource.DataSourceTransactionManager"
id="transactionManager">
<property name="dataSource" ref="dataSource" />
</bean>
</beans>
aspectj-ltw/src/test/resources/META-INF/aop.xml
<!DOCTYPE aspectj PUBLIC
"-//AspectJ//DTD//EN" "http://www.eclipse.org/aspectj/dtd/aspectj.dtd">
<aspectj>
<weaver options="-showWeaveInfo -debug -verbose -XmessageHandlerClass:org.springframework.aop.aspectj.AspectJWeaverMessageHandler">
<include within="mycompany.aspectj_ltw..*"/>
</weaver>
</aspectj>
aspectj-ltw\pom.xml
<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>mycompany</groupId>
<artifactId>aspectj-ltw</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>aspectj-ltw</name>
<properties>
<spring.version>3.0.5.RELEASE</spring.version>
</properties>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.8.2</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>${spring.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aop</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aspects</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-tx</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjrt</artifactId>
<version>1.7.0</version>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.7.0</version>
</dependency>
<dependency>
<groupId>javax.inject</groupId>
<artifactId>javax.inject</artifactId>
<version>1</version>
</dependency>
<dependency>
<groupId>cglib</groupId>
<artifactId>cglib-nodep</artifactId>
<version>2.2</version>
</dependency>
<dependency>
<groupId>commons-dbcp</groupId>
<artifactId>commons-dbcp</artifactId>
<version>1.4</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<version>1.2.143</version>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-core</artifactId>
<version>0.9.24</version>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>0.9.24</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>log4j-over-slf4j</artifactId>
<version>1.6.1</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<forkMode>always</forkMode>
<argLine>
-javaagent:C:/maven-2_local_repo/org/springframework/spring-instrument/3.0.5.RELEASE/spring-instrument-3.0.5.RELEASE.jar
</argLine>
</configuration>
</plugin>
</plugins>
</build>
</project>
VM arguments to run the test:
-javaagent:C:/maven-2_local_repo/org/springframework/spring-instrument/3.0.5.RELEASE/spring-instrument-3.0.5.RELEASE.jar
If I'm not mistaken, the issue here is not due to AspectJ, but rather to the way things work in the precise JUnit use case. When running your test, the MyServiceImplTest class is loaded first, before the Spring context was created (you need the test class' annotations to get the appropriate runner and config locations), hence before any Spring AOP mechanism was leveraged. That is, at least, the explanation I came up with when I faced the very same situation a few months ago... Since the javaagent is there from the JVM startup on, one would have to fully read/understand the weaver's code to precisely explain why it fails here (I didn't :p).
So anyway, the MyServiceImplTest type, along with all its member's types, which are loaded with it - this goes for types in method signatures as well -, cannot be woven.
To work around this:
either avoid using the woven types in the test class members and methods signature (e.g. using interfaces like you did)
or add the AspectJ weaver to your javaagents (in addition to the spring-instrument one); with this, if I recall correctly, Spring should be able to get its AOP-based mechanisms to work properly:
-javaagent:/maven-2_local_repo/org/aspectj/aspectjweaver/1.7.0/aspectjweaver-1.7.0.jar -javaagent:/maven-2_local_repo/org/springframework/spring-instrument/3.0.5.RELEASE/spring-instrument-3.0.5.RELEASE.jar
Nota: in your META-INF/aop.xml, it may be necessary to add the -Xreweavable weaver option.
First of all , if you are using maven, set your pom.xml:
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-instrument</artifactId>
<version>3.1.2.RELEASE</version>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.7</version>
</dependency>
Then you have had to compile your code using the aspectj compiler.
This compiler generate an aop.xml file in META-INF/aop.xml
(I'm using eclipse sts)
After that, I want to run a Junit test.
So you have to set your VM args in the eclipse run configuration window:
-javaagent:${ASPECTJ_WEAVER_1.7}\aspectjweaver-1.7.0.jar -javaagent:${SPRING_INSTRUMENT}\spring-instrument-3.1.2.RELEASE.jar
where ${ASPECTJ_WEAVER_1.7} ${SPRING_INSTRUMENT} are an environtment var. Use the var button to create these vars (is located at bottom right of the window). These vars target to the folders where the aspectjweaver-1.7.0.jar and spring-instrument-3.1.2.RELEASE.jar are located. Follow the asistant to make this. It's not difficult.
Take care that the previous javaagent lines haven't any invisible strange character or similar. It's sound strange but I had to rewrite several times the same line until eclipse said that this line is fine.
Then, you can run your Junit test.
The first you can see is aspectj runtime loading. Later you will see spring loading... and after that your test will run is haven't got any spring problem or similar.
This is a heavy process.
I hope this information can help you
Regards

AspectJ Load Time Weaving with Spring Transaction Manager and Maven

I'm attempting to enable load time weaving with Spring's transaction manager but without too much luck. Currently I'm just trying to run a simple em.persist() in a #Transactional method but it does not appear to running a transaction as seen through: TransactionSynchronizationManager.isActualTransactionActive()
My application context file contains :
<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalEntityManagerFactoryBean">
<property name="persistenceUnitName" value="TEST-pu"/>
</bean>
<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="entityManagerFactory"/>
</bean>
<tx:annotation-driven transaction-manager="transactionManager" mode="aspectj" proxy-target-class="true"/>
And my pom.xml contains:
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-agent</artifactId>
<version>2.5.4</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aspects</artifactId>
<version>3.0.5.RELEASE</version>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjrt</artifactId>
<version>1.6.10</version>
</dependency>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.4</version>
<configuration>
<forkMode>once</forkMode>
<argLine>
-javaagent:${settings.localRepository}/org/springframework/spring-agent/2.5.4/spring-agent-2.5.4.jar
</argLine>
<useSystemClassloader>true</useSystemClassloader>
</configuration>
</plugin>
It would appear as if there is some issue with the setup and while I have come across quite a few examples of how to implement AspectJ / Load time weaving they all seem to be using Eclipse plugins which 1) I am trying to avoid using any sort of plugins and 2) I am using Intellij. Any help would be much appreciated.
Thanks.
Have you added:
<context:load-time-weaver/>
to your setup?

Resources