I'm new to soft. engineering and doing a project for user management and inside of Security package, I have a class called SecurityAspects
where I define @Pointcut
and @Around
.
I'm using Apache Ant to compile the whole program.
SecurityAspects.java
package teste.servicepack.security.logic;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import teste.domain.UserSession;
import teste.servicepack.security.SecurityContextProvider;
import teste.servicepack.security.logic.Exception.FailRoleException;
import teste.servicepack.security.logic.Exception.NotAuthenticatedException;
import teste.servicepack.security.logic.Permission.HasRole;
import teste.utils.HibernateUtils;
import java.util.Arrays;
import java.util.logging.Logger;
@Aspect
public class SecurityAspects {
private static final Logger logger = Logger.getLogger(String.valueOf(SecurityAspects.class));
@Pointcut("@annotation(Transaction)")
public void TransactionPointCut(){}
@Pointcut("@annotation(IsAuthenticated)")
public void isAuthenticatedPointCut(){}
@Pointcut("@annotation(hasRole)")
public void hasRolePointCut(HasRole hasRole){}
@Pointcut("execution(* *(..))")
public void executionPointCut(){}
//Transaction
@Around("TransactionPointCut() && executionPointCut()")
public Object transactionAdvise(ProceedingJoinPoint pjp) throws Throwable{
HibernateUtils.getCurrentSession().beginTransaction();
try {
Object obj = pjp.proceed();
HibernateUtils.getCurrentSession().getTransaction().commit();
logger.info("Transaction finished successfully!");
return obj;
}catch (Exception e){
HibernateUtils.getCurrentSession().getTransaction().rollback();
throw e;
}
}
// isAuthenticated
@Around("isAuthenticatedPointCut() && executionPointCut()")
public Object isAuthenticatedAdvise(ProceedingJoinPoint pjp) throws Throwable
{
logger.info("isAuthenticated");
String cookie = SecurityContextProvider.getInstance().getSecuritySessionContext().getRequester();
UserSession session = (UserSession) HibernateUtils.getCurrentSession().load(UserSession.class,cookie);
if(session.getUser() != null)
return pjp.proceed();
throw new NotAuthenticatedException("Access Denied, not authenticated at " pjp.getSourceLocation().getFileName() " " pjp.getSourceLocation().getLine() " service: " pjp.getSignature().getName());
}
// HasRole
@Around("hasRolePointCut(hasRole) && executionPointCut()")
public Object hasRoleAdvise(ProceedingJoinPoint pjp,HasRole hasRole) throws Throwable
{
logger.info("hasRole");
String cookie = SecurityContextProvider.getInstance().getSecuritySessionContext().getRequester();
UserSession session = (UserSession) HibernateUtils.getCurrentSession().load(UserSession.class,cookie);
String[] rolesIn = hasRole.role().split(",");
String[] roles = session.getUser().getRoles().split(",");
for(String checkRole: rolesIn){
if(Arrays.asList(roles).contains(checkRole)) {
return pjp.proceed();
}
}
throw new FailRoleException("Access Denied, does not have role " hasRole.role() " at " pjp.getSourceLocation().getFileName() " " pjp.getSourceLocation().getLine() " service: " pjp.getSignature().getName());
}
}
build.xml
<?xml version="1.0"?>
<project default="deploy" basedir=".">
<property file="local.properties"/>
<property file="build.properties"/>
<path id="pathref">
<fileset dir="lib/hibernate">
<include name="*.jar"/>
</fileset>
<fileset dir="lib/mysql">
<include name="*.jar"/>
</fileset>
<fileset dir="lib/commons">
<include name="*.jar"/>
</fileset>
<fileset dir="lib/log4j">
<include name="*.jar"/>
</fileset>
<fileset dir="lib/json">
<include name="*.jar"/>
</fileset>
<fileset dir="${TOMCAT_HOME}/lib">
<include name="servlet-api.jar"/>
</fileset>
</path>
<taskdef name="hibernatetool"
classname="org.hibernate.tool.ant.HibernateToolTask"
classpathref="pathref" classpath="${build.dir.classes}"/>
<taskdef name="schemaupdate"
classname="org.hibernate.tool.hbm2ddl.SchemaUpdateTask"
classpathref="pathref" classpath="${build.dir.classes}"/>
<target name="generateUpdateHibernateSql" depends="compile">
<schemaupdate
properties="${build.dir.classes}/teste/domain/jdbc.properties"
quiet="no"
text="no">
<fileset dir="src/java">
<include name="**/*.hbm.xml"/>
</fileset>
</schemaupdate>
</target>
<target name="generateHibernateDomainObjects">
<mkdir dir="src/gen"/>
<replace dir="src/java" value="">
<include name="**/*.hbm.xml"/>
<replacefilter token='<timestamp source="db"' value="<timestamp"/>
</replace>
<hibernatetool>
<configuration>
<fileset dir="src/java">
<include name="**/*.hbm.xml"/>
</fileset>
</configuration>
<hbm2java
jdk5="true"
ejb3="false"
destdir="src/gen"/>
</hibernatetool>
<delete>
<fileset dir="src/gen">
<include name="**/*Impl.java"/>
</fileset>
</delete>
<replace dir="src/java" value="">
<include name="**/*.hbm.xml"/>
<replacefilter token='<timestamp' value='<timestamp source="db"'/>
</replace>
</target>
<target name="initDirs">
<mkdir dir="build"/>
<mkdir dir="build/ant"/>
<mkdir dir="build/ant/classes"/>
<mkdir dir="build/ant/war"/>
<mkdir dir="build/ant/war/WEB-INF"/>
<mkdir dir="build/ant/war/WEB-INF/classes"/>
<mkdir dir="build/ant/war/WEB-INF/lib"/>
</target>
<target name="deploy" depends="build.war">
<copy todir="${TOMCAT_HOME}/webapps/">
<fileset dir="build/ant/">
<include name="war/**/*.*"/>
</fileset>
</copy>
<touch file="${TOMCAT_HOME}/webapps/war/WEB-INF/web.xml"/>
</target>
<target name="build.war" depends="compile">
<copy todir="build/ant/war/WEB-INF" file="conf/web.xml"/>
<copy todir="build/ant/war">
<fileset dir="src/web">
<include name="**/*.*"/>
</fileset>
</copy>
<copy todir="build/ant/war/WEB-INF/classes">
<fileset dir="build/ant/classes">
<include name="**/*.*"/>
</fileset>
</copy>
<copy todir="build/ant/war/WEB-INF/lib">
<fileset dir="lib/hibernate">
<include name="*.jar"/>
</fileset>
<fileset dir="lib/mysql">
<include name="*.jar"/>
</fileset>
<fileset dir="lib/log4j">
<include name="*.jar"/>
</fileset>
<fileset dir="lib/commons">
<include name="*.jar"/>
</fileset>
<fileset dir="lib/json">
<include name="*.jar"/>
</fileset>
</copy>
<touch file="build/ant/war/WEB-INF/web.xml"/>
</target>
<target name="war" depends="build.war">
<war file="build/ant/war.war">
<fileset dir="build/ant/war">
<include name="**/*.*"/>
</fileset>
</war>
</target>
<target name="compile" depends="initDirs">
<javac destdir="build/ant/classes"
debug="true"
encoding="UTF-8"
source="1.8" target="1.8"
classpathref="pathref">
<src path="src/java"/>
<src path="src/gen"/>
</javac>
<copy file="conf/log4j.properties" todir="build/ant/classes"/>
<copy file="conf/hibernate.cfg.xml" todir="build/ant/classes/teste/domain"/>
<copy todir="build/ant/classes">
<fileset dir="src/java">
<include name="**/*.xml"/>
</fileset>
</copy>
<copy file="conf/jdbc.properties" todir="${build.dir.classes}/teste/domain"/>
<replace file="${build.dir.classes}/teste/domain/jdbc.properties">
<replacefilter token="@database.username@" value="${database.username}"/>
<replacefilter token="@database.password@" value="${database.password}"/>
<replacefilter token="@database.connection.url@" value="${database.connection.url}"/>
</replace>
<replace file="${build.dir.classes}/teste/domain/hibernate.cfg.xml">
<replacefilter token="@database.username@" value="${database.username}"/>
<replacefilter token="@database.password@" value="${database.password}"/>
<replacefilter token="@database.connection.url@" value="${database.connection.url}"/>
<replacefilter token="@hibernate.show.sql@" value="${hibernate.show.sql}"/>
</replace>
</target>
</project>
But my problem is, when I try to compile with Ant, I have this error:
/Users/dilantaskin/Downloads/TrabalhoES/src/java/teste/servicepack/security/logic/SecurityAspects.java:3: error: package org.aspectj.lang does not exist
/Users/dilantaskin/Downloads/TrabalhoES/src/java/teste/servicepack/security/logic/SecurityAspects.java:4: error: package org.aspectj.lang.annotation does not exist
Like that I have over 20 errors just because of org.aspectj.lang.
In ide, everything looks fine, nothing stays red like it doesn't support.
I can see that I have aspectjrt.jar and aspectj-1.9.7 inside of External Libraries.
I tried to change the org.aspectj.lang to org.aspectj.lang3 but it doesn't recognize.
Can anyone explain me why do I get errors even though I have necessary jars?
INFO: Im not using Maven
and I think(?) neither Spring
. I have a basic Java
project on IntelliJ
using Tomcat
, Hibernate
, Servlet
and Ant
.
Edit by kriegaex: The author shared an MCVE on GitHub under Edifie/user-management-NF, making the problem reproducible (if first you also download and unzip Tomcat, then point the Ant build to it).
CodePudding user response:
I inspected your project on GitHub, thanks for the link. There is so much wrong with it, I hardly know where to begin:
You committed library JARs instead of doing proper dependency management using Maven, Gradle or, if you insist to stay on Ant, something like Ivy. Dependencies should be downloaded during the build, not committed in a source code management (SCM) repository. Using Maven or Gradle also would have the advantage that IDEs like IntelliJ IDEA or Eclipse can automatically import your projects and also know where to find the dependencies and share them between projects, instead of you redundantly committing them to each of your project SCM repositories and manually adding them to your IDE project configuration. That is just ugly.
One of the JARs in your project is
aspectj-1.9.6.jar
. This is not what you want but an executable installer, the purpose of which is to install AspectJ locally. In there, you also find nested JARs such asaspectjrt.jar
(runtime),aspectjtools.jar
(compiler),aspectjweaver.jar
(load-time weaving agent). You would have to execute that installer and then copy the libraries you need to yourlib
directory.In order for the Java compiler to recognise your AspectJ imports, you need the AspectJ runtime on your classpath, i.e. you can download
aspectjrt-1.9.6.jar
from Maven Central (select "Downloads → jar" in the top right menu). Then you simply copy it tolib
and add this to your Ant script:<fileset dir="lib"> <include name="aspectjrt*.jar"/> </fileset>
Now the projects compiles, but if that achieves what you want depends on whether you want to use Spring AOP or native AspectJ. For the former, no AspectJ compiler is necessary, but your aspects would have to be made Spring components. For the latter, compiling with
javac
is not enough, you need the AspectJ compilerajc
. AspectJ provides its own Ant task for that. If you need the Ant task, you also want to have the AspectJ compiler on that task's classpath (not on the application classpath, only during build time). That would beaspectjtools-1.9.6.jar
.
I am not an Ant user, so I have zero interest in this ancient build tool, but if you are an Ant user, you will know how to finish the job.
There is more wrong with your application, e.g. like I said in my comment, @annotation(Transaction)
and @annotation(IsAuthenticated)
should use fully qualified class names or import the classes and bind the annotations to pointcut parameters, if that is what you need.
I think, you should take a break and learn some Ant and AspectJ basics first, probably also Git basics. Or if you have a choice to switch from Ant to Maven, I strongly advise you to do that and forget Ant. If you are stuck with Ant because your employer requires you to use it, my sincere condolences. But actually, it is just a tool, and if you need it, just learn how to handle it.