How to enable compile-time aspectj weaving for Eclipse embedded Tomcat - eclipse

I'm having a problem trying to make eclipse and aspectj work for Dynamic Web Projects. I'm looking for compile time weaving so I can use the Eclipse Visualisation features.
I've followed the steps given here:
https://forums.oracle.com/forums/thread.jspa?messageID=8591748
using Eclipse Indigo (3.7) with the latest Aspectj eclipse plugin (2.1.3).
The steps were as follows:
[1] Create basic servlet
//imports omitted
public class MyServlet extends HttpServlet{
public void doGet(HttpServletRequest request, HttpServletResponse response){
PrintWriter out= null;
try {
out = response.getWriter();
out.write("hello from MyServlet");
} catch (IOException e) {
e.printStackTrace();
} finally {
if(out!=null)
out.close();
}
}
}
[2] Add servlet to deployment discriptor (web.xml)
<?xml version="1.0" encoding="ISO-8859-1"?>
<web-app xmlns="http://java.sun.com/xml/ns/j2ee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee
http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"
version="2.4">
<servlet>
<servlet-name>MyServlet</servlet-name>
<servlet-class>com.myCompany.MyServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>MyServlet</servlet-name>
<url-pattern>/MyServlet/*</url-pattern>
</servlet-mapping>
</web-app>
[3] Create aspect
package com.myCompany;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public aspect MyServletAspect {
pointcut doGet() :
execution(public void MyServlet.doGet(HttpServletRequest,HttpServletResponse));
after() returning : doGet() {
System.out.println("Hello from doGet (via aspectj)");
}
}
However when I run this no dice - the aspect just doesn't run (servlet writes to response, aspect to console). I did something similar for a regular java project and that works fine.
I note there are guidelines for adding aop.xml into the web app's META-INF directory, however this didn't work for me.
Our goal is to run aspectj non-invasively in development via eclipse for a non-Spring framework (or Maven) project - this should be easy.. but I haven't been able to make it work.
Any suggestions / reference to tutorial for compile-time weaving for web apps in eclipse would be useful. The app server is embedded Tomcat 6 (but can be upgraded to tomcat 7 if required).
The ability to tweak the development environment at runtime without impacting the production code would be great - if it can be made to work.
Responses much appreciated.

I recommend you just download and use Spring STS (Spring's Eclipse) and download/create a Spring Roo project.
Your just going to use the Roo project to boostrap your own project with the correct AspectJ libraries. That is you'll just use its pom file that it generates. You can try to use plain Eclipse and download all the plugins (which is what I do) but its PITA to get everything setup correctly.
The key thing is to get the AspectJ compiler to run instead of the regular Java compiler. This requires a special Maven plugin or Ant plugin. Also you do not need the aop.xml file.
If your using Eclipse you need to make sure that the AspectJ nature is added to the project (usually you right click on the project and select "add natures" "Or convert to...".)
You'll also in Eclipse need to add the Spring Aspects jar to the "Aspect Libraries" which is not the classpath/buildpath.

To use compile time weaving in maven, you need to use the aspectj compiler plugin. See this:
http://maven.apache.org/maven-1.x/plugins/aspectj/
To get your project working in Eclipse, you need to install the AspectJ project configurator for m2eclipse (assuming you are using m2eclipse). You can install it from going to Preferences -> Maven -> Discovery. Open the catalog and look for the AJDT configurator.

Related

Custom TeamCity plugin is uploaded but doesn't seem to get executed

I'm developing a TeamCity plugin and I fail to even get it executed by TeamCity.
I upload the zip file with the plugin and restart TeamCity, then I can see the plugin on the list of external plugins, it also gets unpacked into .BuildServer/plugins/.unpacked but other than that nothing happens.
It doesn't seem that the plugin is running. (I don't even see the plugin name in any logfile)
My simplest attempt was to just create a plugin from maven archetype:
mvn archetype:generate -DarchetypeRepository=http://download.jetbrains.com/teamcity-repository -DarchetypeArtifactId=teamcity-server-plugin -DarchetypeGroupId=org.jetbrains.teamcity.archetypes -DarchetypeVersion=RELEASE
and then only add some logging:
package com.example.plugin;
import jetbrains.buildServer.log.Loggers;
public class AppServer {
public void run() {
Loggers.SERVER.info("I'm running");
}
}
and create the necessary bean with init method:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
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"
default-autowire="constructor">
<bean id="appServer" class="com.example.plugin.AppServer" init-method="run"/>
</beans>
I upload the plugin, restart TeamCity but the log message from AppServer does not appear in any logfile.
What am I missing? How to log this message?
I would expect to see an exception (plus a stacktrace) in the teamcity-server.log file. Are you sure you checked that file?
The behaviour you're describing can be symptomatic of you having built the plugin with a JDK version incompatible with TeamCity's JRE. For example, you build your plugin with Java 8 but your TeamCity is running under Java 7. In that case, the plugin will be detected (as it is in your case) but will crash when TC tries to invoke it.

How to import javax.faces library in Eclipse using JDK8?

Based on the advice to use JSF, the following sample would like to be run in order to learn more about JSF and to implement this technique into the servlet. However, a number of libraries is unable to be imported:
package tobedefinedservlet;
import javax.faces.bean.ManagedBean;
#ManagedBean
public class Hello {
final String world = "Hello World!";
public String getworld() {
return world;
}
}
javax.faces
The import javax.faces cannot be resolved
ManagedBean
ManagedBean cannot be resolved to a type
You have to include a JSF library like for example Mojarra in the classpath of your application.
First of all have a look at the Primefaces user guide (especially chapter 2.2). You can download e.g. Mojarra here and include the JAR or add the dependency to your POM.xml if you are using Maven. Hope that helps.
If you're using maven for build automation, add the latest jsf-api dependency to your pom.xml:
<dependency>
<groupId>javax.faces</groupId>
<artifactId>jsf-api</artifactId>
<version>2.1</version>
</dependency>
Or the latest javax.faces-api implementation:
<dependency>
<groupId>javax.faces</groupId>
<artifactId>javax.faces-api</artifactId>
<version>2.3</version>
</dependency>
However, note that JSF is integrated into most Java EE application servers, such as JBoss.
See also this answer.
in my case ...I went to project properties and in the search engine I wrote facets ... I went to the right of the window and selected the runtime tab and select wildfly ... then apply and apply and close and solve ...
If you're not using maven you have to manually install the jar. You can download it at this link:
javax.faces
If you're using eclipse you can right click your Web App project and click properties at the bottom. Then under the java build path make sure the libraries panel at the top is selected then select the Web App library and on the right click Add External JARS. You can go to your downloads folder and select the jsf-api-2.1.jar and refresh the project and you can now import that annotation.

How to correctly setup Logback in an Eclipse RCP application?

I have spent the last 2 or 3 days trying to get Logback correctly working in my new Eclipse RCP Project. (I'm trying RCP for the first time, but have used logback in other java projects).
My questions to all of you out there are: "Is there a simple plugin for Eclipse RCP (E4) to enable Logback logging? Should the plugin here (http://logback.qos.ch/p2/) be used? If there isn't a simple plugin to use, what is the correct way to enable this logging?"
I've read this page (http://devblog.virtage.com/2012/07/logback-and-eclipse-attaching-logback-xml/) many times and it seems promising, but I haven't been able to get it to work.
I've managed to get a working configuration for logback, that works with RCP 3.x and 4.x. I am building with Tycho, and use features and products to assemble the apps (see the Vogella tutorial for details). The steps are:
In your defining plugin (usually the one containing your application), add dependencies to ch.qos.logback.classic and ch.qos.logback.core, as well as org.slf4j.api. All other plugins just need to depend on org.slf4j.api to access loggers.
In the feature that includes your defining plugin, add the ch.qos.logback.slf4j fragment on the Included PLug-ins page. Without this, SLF4J won't be able to find Logback in the deployed product.
Create a logback.xml file in your defining plugin somewhere in classpath (src/main/resources if you are using Tycho/Maven).
For an e4 application, add a life cycle manager, and initialize Logback in its #ProcessAdditions method:
ILoggerFactory iLoggerFactory = LoggerFactory.getILoggerFactory();
LoggerContext loggerContext = (LoggerContext) iLoggerFactory;
loggerContext.reset();
JoranConfigurator configurator = new JoranConfigurator();
configurator.setContext(loggerContext);
try {
configurator.doConfigure(getClass().getResourceAsStream("/logback.xml"));
} catch (JoranException e) {
throw new IOException(e.getMessage(), e);
}
For an Eclipse 3.x, application, the above code goes into the start() method of your application plugin's Activator.
You will probably want to use a file appender, as standard out is not shown unless you use -consoleLog as a program argument. If you specify the file location as <file>${user.dir}/path/to/file</file>, the file will be created in the application install directory. Generally you would use the workspace metadata directory, so that it is alongside the Eclipse log, e.g. <file>${user.dir}/workspace/.metadata/rcp.log</file>.
Quite simple.
Put your logback.xml file in directory /config (or wherever you want inside your plugin)
In your plugin project (plugin.xml), do the following.
dependencies tab: add : org.slf4j.api,ch.qos.logback.classic ch.qos.logback.core
build tab, "binary build", check the file "config/logback.xml"
In your intialisation class (class pointed by "lifeCycleURI" in plugin.xml) add the following:
#PostContextCreate
public void init()
...
SLF4JConfigurator.configure();
...
}
The SLF4JConfigurator class:
public final class SLF4JConfigurator {
private static final String BUNDLE_NAME = FrameworkUtil.getBundle(SLF4JConfigurator.class).getSymbolicName();
private static final String LOGBACK_XML = "platform:/plugin/" + BUNDLE_NAME + "/config/logback.xml";
public static void configure() {
// Reset Current SLF4J config
JoranConfigurator configurator = new JoranConfigurator();
LoggerContext loggerContext = (LoggerContext) LoggerFactory.getILoggerFactory();
configurator.setContext(loggerContext);
loggerContext.reset();
// Read Configuration file
try {
URL configFile = new URL(LOGBACK_XML);
InputStream configurationStream = configFile.openStream();
configurator.doConfigure(configurationStream);
configurationStream.close();
} catch (JoranException | IOException e) {
// Problem when reading file...
e.printStackTrace();
}
StatusPrinter.printInCaseOfErrorsOrWarnings(loggerContext);
// Confirm message
Logger logger = LoggerFactory.getLogger(SLF4JConfigurator.class);
logger.info("Logging configuration initialised.");
}
}
Include the 3 dependencies in your "product" defintion. If you build with tycho, the slf4j+logback plugins plugins from eclipse will be automatically bundled with your app, nothing specific to add to your pom files.
This is how I do it in JMSToolBox (On sourceforge)
Here is an excerpt of my working pom.xml of a plugin of an RCP app:
<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<modelVersion>4.0.0</modelVersion>
<groupId>es.fcc.rds</groupId>
<artifactId>fcc.ima.oda</artifactId>
<version>1.0.0-SNAPSHOT</version>
<packaging>eclipse-plugin</packaging>
<properties>
<tycho.version>0.19.0</tycho.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<repositories>
<repository>
<id>eclipse</id>
<url>http://download.eclipse.org/releases/kepler</url>
<layout>p2</layout>
</repository>
<repository>
<id>logback</id>
<url>http://logback.qos.ch/p2/</url>
<layout>p2</layout>
</repository>
</repositories>
....
As you can see, I'm using the http://logback.qos.ch/p2/ repository.
Note: after many months of working ok, it now fails intermitently, maybe due to problems of the p2 repository.

Spring context:component-scan fails to find components in another Eclipse project dependency referenced in POM

I am working on a GWT web application split across two Eclipse Projects (myclient & myservice).
The myclient project references the myservice project via a dependency in the POM.
<dependency>
<groupId>com.myproject</groupId>
<artifactId>myservices</artifactId>
<version>1.0.0</version>
</dependency>
The myclient project has a WAR directory src/main/webapp. The output folder for the myclient project is src/main/webapp/WEB-INF/classes.
The myclient project has a Spring descriptor application-context.xml with the following
<context:component-scan base-package="com.myproject.myclient, com.myproject.myservices"/>
and the web.xml
<web-app>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/application-context.xml</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<listener>
<listener-class>org.springframework.web.context.request.RequestContextListener</listener-class>
</listener>
...
</web-app>
I have several files in the myservices project annotated as spring #Component, #Service, #Configuration but these are not picked up by the component scan when I run the GWT application in Eclipse. As a test I experimented with placing an #Component in the myclient project and this was successfully created.
I believe the following log entry during application startup indicates the source of the problem
org.springframework.core.io.support.PathMatchingResourcePatternResolver - Resolved location pattern [classpath*:com/myproject/myservices/**/*.class] to resources []
the location pattern for the myclient project resolves to all the resources on the classpath but for myservices no resources are found.
I experimented with building the myservices project JAR and placing this JAR into the src/main/webapp/WEB-INF/lib folder of the myclient project. When I do this the component scanning works. However for development I don't want to have to build and copy a JAR everytime I make changes to the myservices project. I imagine that the component scanning should work on a project referenced through the POM without having to the build that project but after much experimenting I have been unable to get this working.
Be sure that in the deployment assembly (right click your web project and select "deployment assembly" of your myclient project it is configured to deploy the jar that is outputted by the myservices project. If you are using maven, the m2e, m2e-wtp project configurators should do this deployment assembly setup automatically.
Once you have deployment assembly settings properly configured, now when you deploy a project to your server using the Eclispe server adapter publish mechanism, everything should get deployed and the myservices jar would get placed in the right spot for your myclient project.
But make sure you the latest version of m2e-wtp installed. This way your configuration in your pom.xml and deployment assembly will get correctly configured.
Try splitting your application-context.xml into 2 separate files:
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:service-context.xml,classpath:client-context.xml</param-value>
</context-param>
myservices/src/main/resources/service-context.xml:
<context:component-scan base-package="com.myproject.myservices"/>
myclient/src/main/resources/client-context.xml:
<context:component-scan base-package="com.myproject.myclient"/>
Try this :
<context:component-scan base-package="com.myproject"/>
Please check the following things:
Is your serviceproject present "only" as jar or is the whole project available via workspace resolution. This can be checked via maven-context-menue (Disable/Enable Workspaceresolution)
The layout of the webapp under src/main/webapp is okay. BUT do i get you right that all classes are copied there? If so, you should make sure everything is under target directory. So please check whether a maven call "clean package" generates a webappstructure under the target folder and all required libs (e.g. myservice) exist under target\$your-webarchivename\WEB-INF\lib
Check that packaging in myservice pom.xml is set to jar (you probably have this, right?)
it's obvious that your service jar is not included in your client project's build path. this is the only root cause.
Make sure 3 points:
you have run mvn clean install under your service project which has correct pom.xml.
you have run mvn eclipse:eclipse under your client project. this will pull out all your dependency project.
check your client eclipse project's build path dialog. is there your service jar in the list? Make sure this
You better once look this tutorial
http://fusesource.com/docs/framework/2.2/deploy_guide/CXFServletDeploySpring.html

Eclipse Maven Web Project Servlet Mappings

I have set up my maven project using the m2e plugin in eclipse indigo, and transformed it to an eclipse dynamic web project using mvn eclipse:eclipse -Dwtpversion=1.5. I have managed to get the project up and running in tomcat7, except for my servlets, for which I cannot create the servlet mappings.
I have tried modifying the web.xml file but it throws a ClassNotFoundException. Directory Structure and web.xml :
(ROOT)
+src
+main
+resources
+DrawInitialMap.java
+webapp
(WebContent here)
<web-app>
<servlet>
<servlet-name>DrawInitialMap</servlet-name>
<servlet-class>(groupId).(artifactId).src.main.resources.DrawInitialMap</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>DrawInitialMap</servlet-name>
<url-pattern>/drawInitialMap.do</url-pattern>
</servlet-mapping>
(...)
</web-app>
While the #WebServlet annotation also fails to map the servlet :
#WebServlet(name="drawInitialMap", description="visualizes ttrp on html5 canvas", urlPatterns={"/drawInitialMap.do"})
Thank you in advance, and notify if you need any more of the code.
PS : Keep in mind that the servlet worked perfectly in Dynamic Web Project mode, without Maven
There are several issues.
You should stop using eclipse:eclipse. Instead, install WTP integration for M2E from Eclipse Marketplace
In Maven project, your DrawInitialMap should be in /src/main/classes folder. So, it will be compiled as per default Maven project conventions
The servlet-class element in web.xml requires full class name, i.e. no things like (groupId).(artifactId).src.main.resources.