AspectJ and Map<String,Object> Array - aspectj

I am using AJDT 2.2.4 which is build on AspectJ 1.81.
Consider this simple aspect:
#Aspect
public class SampleAspect {
#Before("#annotation(logMe)")
public void beforeAdvice(JoinPoint joinPoint, LogMe logMe) {
System.out.println("Before the method");
}
}
It print some text before LogMe annotation which is :
#Retention(RetentionPolicy.RUNTIME)
#Target(ElementType.METHOD)
public #interface LogMe {}
Now, I apply this annotation to some method as:
public class DummyClass {
#LogMe
public void doSomething() {
SampleUtil sampleUtil = new SampleUtil();
//pass null for simplicity !
sampleUtil.sampleMethod(null);
System.out.println("Do Something");
}
}
The SampleUtil is
public class SampleUtil {
public void sampleMethod(
Map<String, Object>[] mapArray){
}
}
I get this warning:
can not resolve this member:
void foo.SampleUtil.sampleMethod(java.util.Map[]) [Xlint:unresolvableMember]
If I change the sampleMethod parameter to something else like Map<String, Object> aMap the error will go.
Why do I get this warning ?!

That warning means that it can't find foo.SampleUtil on the inpath. The inpath is similar to the classpath, and is used to determine what the aspects weave against.
I am guessing that foo.SampleUtil is in another project and this means that you need to explicitly add the project to your inpath.
Since you are using AJDT inside of Eclipse, you can go to the aspect project's properties page and select the AspectJ build path tab. Choose Inpath and add the other project.

Related

Gradle standalone plugin unknown property when loaded from github repository

I've created a simple standalone Gradle plugin in Java and a Maven repository on GitHub for publishing the plugin. Everything works fine except retrieving project properties that should be available with the plugin. When I apply the plugin in another Gradle project, it can't find those properties.
It happens only when the plugin is loaded from the remote repository on GitHub. When loaded from a local repository, it works. Can the plugin implementation be somehow set to provide properties even from a remote repository? Or is this some GitHub feature that can't be hacked?
Details follow:
My build.gradle in the another project looks something like this:
buildscript {
repositories {
maven {
url "GITHUB_REPO_URL"
}
}
dependencies {
classpath "custom_plugin_group:custom_plugin:1.0"
}
}
apply plugin: "custom_plugin"
task propertyTest {
doLast {
println project.customProperty
}
}
When I try to run the the task propertyTest, it fails complaining that "Could not get unknown property 'customProperty' for root project 'another_project' of type org.gradle.api.Project."
I'm creating the property in the method apply in the main plugin class. I have tried following three approaches:
// First approach - adding a simple value to extensions
public class CustomPlugin implements Plugin<Project> {
#Override
public void apply(Project project) {
project.getExtensions().add("customProperty", "Custom property value");
}
}
// Second approach - setting extra property to extensions
public class CustomPlugin implements Plugin<Project> {
#Override
public void apply(Project project) {
project.getExtensions().getExtraProperties().set("customProperty", "Custom property value");
}
}
// Third approach - adding a property instance to extensions
public class CustomPlugin implements Plugin<Project> {
#Override
public void apply(Project project) {
Property<String> customProperty = project.getObjects().property(String.class);
customProperty.set("Custom property value");
project.getExtensions().add("customProperty ", customProperty);
}
}
For creating extensions for your Gradle plugin you need create POJO class with fields:
class YourExtension {
String customProperty
}
And then create extension in your plugin class:
public class CustomPlugin implements Plugin<Project> {
#Override
public void apply(Project project) {
project.getExtensions().create("extensionName", YourExtension.class);
}
}
Now you can use extension in build.gradle file:
extensionName {
customProperty = "value"
}

How to configure a Listener to override the behaviour of the class LoggingReporter in Citrus?

I'm looking for a way to remove stacktraces of fails assertions when using the framework Citrus.
This is done in testNg like this:
public class NoStackTraceListener implements ITestListener {
...
#Override
public void onTestFailure(ITestResult iTestResult) {
Throwable th = iTestResult.getThrowable();
if (Objects.nonNull(th)) {
System.out.println(th.getMessage());
iTestResult.setThrowable(null);
}
}
...
}
#Listeners({ NoStackTraceListener.class })
class A {...}
But I can't find any example of usgin the class 'TestListener' or others in order to override the supplied implementation of 'LoggingReporter'
Please do anyone has already overrided a Listener using framework citrus and could give the snippet to do so ?
Thanks
You need to add the custom reporter as bean to the Spring application context:
#Bean
public NoStackTraceReporter noStackTraceReporter() {
return new NoStackTraceReporter();
}
You can also overwrite the default logging reporter by choosing the bean name loggingReporter
#Bean
public NoStackTraceReporter loggingReporter() {
return new NoStackTraceReporter();
}
The NoStackTraceReporter implementation is then able to overwrite the specific event handler for failed tests:
public class NoStackTraceReporter extends LoggingReporter {
...
#Override
public void onTestFailure(TestCase test, Throwable cause) {
// do something customized
}
...
}
Also you may overwrite the generateTestResults() method in the reporter interface in order to customize logging results.
You can also follow the sample http://www.citrusframework.org/samples/reporting/ that demonstrates how to add customized reporters in Citrus.

Problems when using EntityFilteringFeature and SelectableEntityFilteringFeature with Jersey 2

I'm new to Jersey 2 and JAX-RS, so probably I'm missing something.
What I'm trying to do is a test program to define a coding style in rest services developing.
The test was written in JAVA and uses JERSEY 2.22.2, JDK 1.8.31, MOXY AS JSON Provider.
I defined a Resource with GET methods to support LIST/DETAIL. Due to the size of my POJO, I used some filters and everything was fine.
// 1) First of all I defined the annotation.
#Target({ElementType.TYPE, ElementType.METHOD, ElementType.FIELD})
#Retention(RetentionPolicy.RUNTIME)
#Documented
#EntityFiltering
public #interface MyDetailView {
public static class Factory extends AnnotationLiteral<MyDetailView>
implements MyDetailView {
private Factory() {
}
public static MyDetailView get() {
return new Factory();
}
}
// 2) Once defined the annotation, I used to
// programmaticaly exclude the list of subItems in the response...
#XmlRootElement
public class MyPojo {
...
//*** THIS SHOULD BE FILTERED IF THE ANNOTATION IS NOT SPECIFIED IN THE RESPONSE ***
#MyDetailView
private List<SubItem> subItems = new ArrayList<SubItem>();
public List<SubItem> getSubItems() {
return subItems;
}
public void setSubItems(List<SubItem> subItems) {
this.subItems = subItems;
}
}
// 3) I registered the EntityFilteringFeature
public class ApplicationConfig extends ResourceConfig {
public ApplicationConfig() {
....
register(EntityFilteringFeature.class);
}
// 4) Finally, I wrote the code to include/exclude the subItems
/*
The Resource class has getCollection() and getItem() methods...
getCollection() adds the annotation only if filterStyle="detail"
getItem() always add the annotation
*/
#Path(....)
#Produces(MediaType.APPLICATION_JSON)
#Consumes(MediaType.APPLICATION_JSON)
public class MyResource extends SecuredResource {
//filterStyle -> "detail" means MyDetailAnnotation
#GET
public Response getCollection(
#QueryParam("filterStyle") String filterStyle,
#Context UriInfo uriInfo) {
//THIS CODE AFFECTS THE RESPONSE
boolean detailedResponse = "detail".equals(filterStyle);
Annotation[] responseAnnotations = detailedResponse
? new Annotation[0]
: new Annotation[]{MyDetailView.Factory.get()};
//pojo collection...
MyPagedCollection myCollection = new MyPagedCollection();
//.....
ResponseBuilder builder = Response.ok();
return builder.entity(myCollection, responseAnnotations).build();
}
#GET
#Path("/{id}")
public Response getItem(#PathParam("{id}") String idS, #Context UriInfo uriInfo) {
MyPOJO pojo = ...
Annotation[] responseAnnotations = new Annotation[]{MyDetailView.Factory.get()};
return Response.ok().entity(pojo, responseAnnotations).build();
}
}
After the first test, I tried to use the SelectableEntityFilteringFeature to allow the client to ask for specific fields in the detail, so I changed the ApplicationConfig
public class ApplicationConfig extends ResourceConfig {
public ApplicationConfig() {
....
register(EntityFilteringFeature.class);
register(SelectableEntityFilteringFeature.class);
property(SelectableEntityFilteringFeature.QUERY_PARAM_NAME, "fields");
}
and I've add the "fields" QueryParam to the Resource getItem() method...
#GET
#Path("/{id}")
public Response getDetail(#PathParam({id}) String id,
#QueryParam("fields") String fields,
#Context UriInfo uriInfo) {
....
But as long as I registered the SelectableEntityFilteringFeature class, the EntityFilteringFeature class stopped working. I tried to add "fields" parameter to one of the Resource methods, it worked perfectly. But the MyDetailAnnotation was completely useless.
I tried to register it using a DynamicFeature
public class MyDynamicFeature implements DynamicFeature {
#Override
public void configure(ResourceInfo resourceInfo, FeatureContext context) {
if ("MyResource".equals(resourceInfo.getResourceClass().getSimpleName())
&& "getItem".equals(resourceInfo.getResourceMethod().getName())) {
//*** IS THE CORRECT WAY TO BIND A FEATURE TO A METHOD? ***
//
context.register(SelectableEntityFilteringFeature.class);
context.property(SelectableEntityFilteringFeature.QUERY_PARAM_NAME, "fields");
}
}
Now the questions:
1) Why registering both the SelectableEntityFilteringFeature feature breaks the EntityFilteringFeature?
2) What is the correct way to bind a feature to a method with the DynamicFeature interface?
Thanks in advance.
This is my first post to Stack Overflow, I hope it was written complaining the rules.
Short answer: you can't. It appears to be a bug as of 2.25.1 and up to 2.26(that I tested with). https://github.com/jersey/jersey/issues/3523
SelectableEntityFilteringFeature implictily registers EntityFilteringFeature (As mentioned here). So I don't see a need to add this.
Since you need Annotation based filtering, you can exclude registering SelectableEntityFilteringFeature.
You can just do,
// Set entity-filtering scope via configuration.
.property(EntityFilteringFeature.ENTITY_FILTERING_SCOPE, new Annotation[] {MyDetailView.Factory.get()})
// Register the EntityFilteringFeature.
.register(EntityFilteringFeature.class)
// Further configuration of ResourceConfig.
You can refer to this example for usage and this example for registering the filter.
So you can remove SelectableEntityFilteringFeature and try just the above mentioned way to register it.

How to access XSSAPI from custom jsp Java class?

I am creating a custom tag library using http://www.cqblueprints.com/xwiki/bin/view/Blue+Prints/Writing+A+JSP+Custom+Tag+Library to produce XSS-proof links from my custom components. I have taken this to a tag since I will need to do other bits of work and to avoid writing scriptlets on the JSP files (I have posted the code at the end).
I wanted to use the XSSAPI from my Java class, but looking at the javadoc for XSSAPI I see that it's an interface; when using it in a JSP file it's an object that is initialized invoking <cq:defineObjects/>.
Does anyone have any ideas on how to do this? There is a method in the XSSAPI class called getRequestSpecificAPI(slingRequest) but it's not static, and I have run out of ideas right now.
#JspTag
public class FixInternalLinkTag extends CqSimpleTagSupport {
private String pathToPage;
#Override
public void doTag() throws JspException, IOException {
XSSAPI xssAPI; // ToDo how to get a reference to this?
urlPointingToPage = xssAPI.getValidHref(urlPointingToPage);
getJspWriter().write(urlPointingToPage);
}
public String getPathToPage() {
return pathToPage;
}
#JspTagAttribute(required = true, rtexprvalue = true)
public void setPathToPage(String pathToPage) {
this.pathToPage = pathToPage;
}
}
If you make your tag class an osgi service
#Component(immediate = true, metatype = true, description = "User Group Finder")
#Service
public class MyClass { ...
you can then use
#Reference
XSSAPI xssapi;
to pull in the implementation of XSSAPI. Then you can use it
xssapi.getRequestSpecificAPI(slingRequest);

Getting TinyIoc current container in a Nancy project

I'm building a small Nancy web project.
In a method of one of my classes (not a nancy module), I would like to basically do:
var myThing = TinyIoC.TinyIoCContainer.Current.Resolve<IMyThing>();
However, there is only one registration in .Current (non public members, _RegisteredTypes) which is:
TinyIoC.TinyIoCContainer.TypeRegistration
Naturally, in my above code, I'm getting:
Unable to resolve type: My.Namespace.IMyThing
So, I guess I'm not getting the same container registered in my bootstrapper?
Is there a way to get at it?
EDIT
To flesh out a bit more of what I'm trying to do:
Basically, my url structure looks something like:
/{myType}/{myMethod}
So, the idea being, going to: /customer/ShowAllWithTheNameAlex would load the Customer service, and execute the showAllWithTheNameAlex method
How I do this is:
public interface IService
{
void DoSomething();
IEnumerable<string> GetSomeThings();
}
I then have an abstract base class, with a method GetService that returns the service.
It's here that i'm trying to use the TinyIoC.TinyIoCContainer.Current.Resolve();
In this case, it would be TinyIoC.TinyIoCContainer.Current.Resolve("typeName");
public abstract class Service : IService
{
abstract void DoSomething();
abstract IEnumerable<string> GetSomeThings();
public static IService GetService(string type)
{
//currently, i'm doing this with reflection....
}
}
Here's my implementation of the service.
public class CustomerService : Service
{
public void DoSomething()
{
//do stuff
}
public IEnumerable<string> GetSomeThings()
{
//return stuff
}
public IEnumerable<Customer> ShowAllWithTheNameAlex()
{
//return
}
}
Finally, I have my Nancy Module, that looks like:
public class MyModule : NancyModule
{
public MyModule()
{
Get["/{typeName}/{methodName}"] = p => ExecuteMethod(p.typeName, p.methodName);
}
private dynamic ExecuteMethod(string typeName, string methodName)
{
var service = Service.GetService(typeName);
var result = service.GetType().GetMethod(methodName).Invoke(service, null);
//do stuff
return result; //or whatever
}
}
#alexjamesbrown - The short answer is, you don't. Nancy was specifically designed so that you did not deal with the container directly. You mention that the class, that you want to take a dependency on IMyThing, is not a NancyModule. Well this is not an issue, as long as one of your modules has a reference to it, then those dependencies can also have their own dependencies that will be satisfied at runtime.
public interface IGreetingMessageService
{
string GetMessage();
}
public class GreetingMessageService: IGreetingMessageService
{
public string GetMessage()
{
return "Hi!";
}
}
public interface IGreeter
{
string Greet();
}
public class Greeter
{
private readonly IGreetingMessageService service;
public Greeter(IGreetingMessageService service)
{
this.service = service;
}
public string Greet()
{
return this.service.GetMessage();
}
}
public class GreetingsModule : NancyModule
{
public GreetingModule(IGreeter greeter)
{
Get["/"] = x => greeter.Greet();
}
}
The above will work just fine and Greeter will have it's dependency on IGreetingMessageService satisfied at runtime
I have had a very similar issue, needing to "share" the container. The reason this is an issue is that my program runs as a service using Nancy self hosting to provide a REST API. My modules have dependencies which are injected by Nancy itself, but the other parts of the app which are not referenced from modules also need dependencies injected.
Multiple containers are not a sensible option here (or anywhere really), I need to share the container between Nancy and the rest of the app.
I simply did the following
(I'm using Autofac but I suspect that TinyIoC in similar)
public class Bootstrapper : AutofacNancyBootstrapper
{
private static readonly Lazy<ILifetimeScope> container = new Lazy<ILifetimeScope>(RegisterTypes);
public static ILifetimeScope Container => container.Value;
protected override ILifetimeScope GetApplicationContainer()
{
return container.Value;
}
// Create container and register my types
private static ILifetimeScope RegisterTypes()
{
var builder = new ContainerBuilder();
// Register all my own types.....
return builder.Build();
}
}
Then, in my main code, I can use the container myself
public class Program
{
public static void Main(string[] args)
{
// Resolve main service with all its dependencies
var service = Bootstrapper.Container.Resolve<Service>();
service.Run();
}
}
As my NancyHost is within the Service, the container is constructed (once) upon its first use in main, this static is then used when Nancy gets round to creating the Bootstrapper itself.
In an ideal world, I wouldn't really want a globally accessible container, normally it would be local to the main function.
In this particular case "not dealing with the container directly" is highly problematic:
public interface IFoo {}
public class Foo : IFoo { public Foo(string bar) {} }
Assume IFoo already is a constructor dependency of a Nancy module.
Note the Foo constructor's string dependency. I need to communicate to the container to use that constructor for an IFoo singleton, when encountered as a Nancy module dependency. I need to register that on the TinyIoC instance NancyFx uses, and pass in the actual value of bar.