SlingServletFilter annotation doesn't generate properties - osgi

I am trying to annotate a sling filter in AEM 6.4 SP2 with the new
#SlingServletFilter(scope=SlingServletFilterScope.REQUEST)
annotation. After deploying I don't see the property "sling.filter.scope = REQUEST" in the Felix console and the servlet is also not triggered.
Any idea why?
The OSGI-standard annotations do work:
#Component(service = Filter.class,
property = {SLING_FILTER_SCOPE + "=" + FILTER_SCOPE_REQUEST)

Very probably the version of the bndtool is too low (at least 4.0.0).
Depending, what you use
bnd-maven-plugin 4.0.0, or
maven-bundle-plugin 3.0.0
See https://sling.apache.org/documentation/the-sling-engine/servlets.html (some details on bndtools are in the video)

Related

Spring AspectJ Load Time Weaving not working with 5.3.3 and Tomcat 9.0.37

I am involved in a review task of an older project. The task is to update certain libraries to more recent versions. This project successfully used load-time-weaving with spring (4.3.14.RELEASE) together with AspectJ (1.9.0) and Tomcat 8.0.20 under JDK 8 with. Now spring shall be updated to the most recent version (5.3.3 at the moment) and also the Tomcat version shall be lifted to a recent version (9.0.37 targeted for the moment). The server shall be running under JDK 11. After upgrading the libraries, we recognized that AspectJ was not working anymore. So I started to debug into this. AspectJ is activated from an XML configuration like this:
<context:load-time-weaver />
Debugging the startup of the container a stumbled over this piece of code in org.springframework.context.config.LoadTimeWeaverBeanDefinitionParser:
protected boolean isAspectJWeavingEnabled(String value, ParserContext parserContext) {
if ("on".equals(value)) {
return true;
}
else if ("off".equals(value)) {
return false;
}
else {
// Determine default...
ClassLoader cl = parserContext.getReaderContext().getBeanClassLoader();
return (cl != null && cl.getResource(AspectJWeavingEnabler.ASPECTJ_AOP_XML_RESOURCE) != null);
}
}
As we do not provide any attribute to the XML tag, AspectJ is in auto-detect mode causing the code in the else branch to be executed. There the reference to the classloader is null, leading to AspectJ being disabled.
An attempt to explicitly activate AspectJ by passing <context:load-time-weaver aspectj-weaving="on"/> had no effect in the end. AspectJ was set active and the definitions were loaded but none of the Aspect definitions (META-INF/aop.xml) were detected applied. As we have changed nothing so far by means of the AspectJ functionality or package structure, something must have changed in spring from 4.3.14 to 5.3.3) or AspectJ (1.9.0 to 1.9.4). A quick view in the GitHub repo showed my only one significant change. But debugging this, the classloader used before the change was also null.
Has anyone had similar problems getting AspectJ to work this way? It looks to me that the problem is detecting the aop.xml files on the classpath.
EDIT:
I have made some more research using different combinations of JDK and Tomcat versions. The problem is not related to those two. When upgrading spring version by version, I found out that it worked fine till 5.1.20.RELEASE. Starting with 5.2.0.RELEASE my problems start. Meanwhile I have AspectJ logging active so I can see that some classes are woven but the majority of those classes I expect being woven, are not.
This was caused by a regression in spring framework since 5.2.0.RELEASE. Here is the issue for that.

Custom properties in Spring Boot project using Gradle

In my Spring Boot project (1.5.6.RELEASE) that I build using gradle, I want to include some custom properties. The approach laid out in the documentation does not seem to work (on build, I get: Could not set unknown property 'additional' for task ':properties' of type org.gradle.api.tasks.diagnostics.PropertyReportTask.):
springBoot {
buildInfo {
properties {
additional = [
'a': 'alpha',
'b': 'bravo'
]
}
}
}
Luckily this approach, which I found here, does work for me (no compile error and I'm then able to access the property from my code):
springBoot{
buildInfo {
additionalProperties = [
'testpropertykey': 'testpropertyvalue'
]
}
}
But, since the former is the "officially" documented approach, I would prefer to take that approach. How would I get the former approach to work? I assume I'm missing something - unless the documentation is wrong or maybe this changed from Spring Boot 1.5.6.RELEASE.
The docs you linked are for the current version of the plugin which aligns with the current GA version of Spring Boot: 2.1.7
Version 1.5.x of the plugin does have a additionalProperties field: https://github.com/spring-projects/spring-boot/blob/1.5.x/spring-boot-tools/spring-boot-gradle-plugin/src/main/java/org/springframework/boot/gradle/buildinfo/BuildInfo.java#L66
The 2.1.x version does not and you use properties instead: https://github.com/spring-projects/spring-boot/blob/2.1.x/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/main/java/org/springframework/boot/gradle/tasks/buildinfo/BuildInfo.java#L45
Suggest you migrate/upgrade to Spring Boot 2.1.x or 2.2.x when that is released soon since 1.5.x has already reached EOL: https://spring.io/blog/2018/07/30/spring-boot-1-x-eol-aug-1st-2019

Spring Boot with Hibernate Search can't find org.hibernate.query.ParameterMetadata

I have a fairly straight forward Spring Boot 1.5.2 application using Hibernate Search. JPA stuff works just fine.
I get Caused by: java.lang.ClassNotFoundException: org.hibernate.query.ParameterMetadata when running a search.
The code looks somewhat like this. Used to run in Wildfly, but I'm migrating to Spring Boot.
FullTextEntityManager fullTextEntityManager = Search.getFullTextEntityManager(em);
QueryBuilder qb = fullTextEntityManager.getSearchFactory()
.buildQueryBuilder()
.forEntity(Customer.class)
.get();
org.apache.lucene.search.Query
luceneQuery = qb.keyword()
.wildcard()
.onField("primaryParty.firstName")
.andField("primaryParty.sureName")
.andField("customerNumber")
.matching(query.trim() + "*")
.createQuery();
javax.persistence.Query jpaQuery =
fullTextEntityManager.createFullTextQuery(luceneQuery, Customer.class);
List<Customer> result = jpaQuery.getResultList();
Hibernate Core 5.0.12 is pulled in via Spring Boot, but the class is not there.
According to this: https://cia.sourceforge.io/tattleTaleReport/jar/hibernate-search-orm-5.7.0.Final.jar.html
i should expect to find it in hibernate-search-orm 5.7.0.Final. But from what I can see this jar only contains the org.hibernate.search package and no org.hibernate.query package. Can't find the class in any other package in that jar either, but it exists in a number of other packages on the class path.
Is the problem
javax.persistence.Query
If so, what to use instead? Or is the problem elsewhere?
Hibernate Search 5.7.0.Final is only compatible with Hibernate ORM 5.2.3.Final and later.
You should either:
downgrade Hibernate Search to 5.6.1.Final
or upgrade Hibernate ORM to version 5.2.3.Final or later. With Spring Boot, I'm afraid you would have to use and unstable version of Spring Boot, namely 2.0.0.BUILD-SNAPSHOT
EDIT: actually, it seems you can use Hibernate ORM 5.2+ with Spring Boot 1.5; see this sample. Be careful to use 5.2.3.Final or later, though (the sample uses 5.2.0.Final, which won't work).
By the way, the link you provided only mentions org.hibernate.query because of OSGi support, which probably isn't relevant to you. It happens that hibernate-search-orm (the module integrating Hibernate Search to Hibernate ORM) both imports and re-exports the org.hibernate.query package, but it doesn't provide it itself.
I was getting the same issue due to using 5.7.0.Final jar and it was not compatible. This issue got resolved by changing downgrade jar version.
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-search-orm</artifactId>
<version>5.6.1.Final</version>

Spring MVC 4 REST with protocol buffers not working

I am trying to use Spring MVC 4's Rest templates to support google protocol buffers as message format. I have am following this post on Spring framework blog
spring-mvc-google-protocol-buffers
I checked out the sourceCode trying to implement it in my environment.
I have two issues- I cannot get it to compile when I turn Java.version to 1.6 and i cannot get it to work as a webapp (don't know what
will be the context-root of the converted war file)
-Details-
I have a requirement to make this code work as a web-app and deploy on java6 container (weblogic 10.3.6 -servlet 2.5 compliant)
So i changed the java 8 features from the codebase to make it Java 6 compatible.
The only problem is when I change the pom.xml's following section
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<start-class>demo.DemoApplication</start-class>
<java.version>1.8</java.version>
</properties>
to change the java.version to 1.6 value, then try to do mvn clean install , the DemoApplicationTests class fails to compile with this error.
-google-protocol-buffers-master\src\test\java\demo\DemoApplicationTests.java:28: cannot find symbol
[ERROR] symbol : constructor RestTemplate(java.util.List<org.springframework.http.converter.protobuf.ProtobufHttpMessageConverter>) is not defined
[ERROR] location: class org.springframework.web.client.RestTemplate
The following link shows that Spring codebase normally doesn't have any Java 8 specific source code so not sure why this code only compiles in Java 8
https://spring.io/blog/2015/04/03/how-spring-achieves-compatibility-with-java-6-7-and-8
--------------------------------------------------------------------------------
The following link shows how to convert a spring boot application to a WAR app.
I did change the pom.xml packaging option to war.
The code gets build by mvn clean install without issues and the .war file gets generated.
But there's no web.xml - so i cannot tell what will be the context-root of the deployed web app.
I either way deployed the webapp on weblogic 10.3.6 ( which is java 6 compatible)
and it deployed fine.
But when I run the DemoApplicationTests (that I have changed to point straight to the URL
using this call (got the context-root from the weblogic console by clicking on the deployed web app)
ResponseEntity<CustomerProtos.Customer> customer = restTemplate.getForEntity(
"http://127.0.0.1:7001/demo-0.0.1-SNAPSHOT/customers/2", CustomerProtos.Customer.class);
I keep getting 404 not found error.
I have put up my changed code here.
https://github.com/robinbajaj123/spring-and-google-protocol-buffers
Your feedback will be appreciated.
You'd need to convert the Spring Boot app to also be a valid Servlet application. If you were using Servlet 3 or later and chose a .war-based deployment from start.spring.io you'd get a ServletIntializer which is a Java class that is the programmatic equivalent of web.xml. Since you're using 2.5, not 3.0, you need an explicit web.xml. You might check out this sample on how to get a Boot app hoisted up in a Servlet 2.5 environment, though using Servlet 2.5 is not recommended!. It's worth mentioning that Servlet 3.0 support was introduced in 2009..
Finally, this code uses Java 8 lambdas. You'll need to replace the lambdas with Java 6-equivalent code. One example I see is:
#Bean
CustomerRepository customerRepository() {
...
The last line in the #Bean definition returns a lambda: customers::get. Replace it with:
final Map<Integer, CustomerProtos.Customer> customers =
new ConcurrentHashMap<Integer, CustomerProtos.Customer>();
return new CustomerRepository() {
public CustomerProtos.Customer findById(int id) {
return customers.get( id) ;
}
};
Similarly, replace the forEach method in the List w/ an old-school for-in loop:
for (CustomerProtos.Customer c : Arrays.asList( ... )) {
customers.put(c.getId(), c);
}

Using Spring DSL in a Grails Plugin

I'm trying to use the Spring DSL functionality in a Grails plugin. However, it doesn't work. Here's what I have in my plugin's conf/spring/resources.groovy file:
import org.springframework.aop.scope.ScopedProxyFactoryBean
// Place your Spring DSL code here
beans = {
baseSvcProxy(ScopedProxyFactoryBean) {
targetBeanName = 'baseService'
proxyTargetClass = true
}
}
However, it seems to be completely ignored. If I move the exact same code to the application's conf/spring/resources.groovy file everything works perfectly. Is there something that needs to be done differently for plugins for this to work?
In order to modify the spring context from a Grails plugin you need to use the doWithSpring section of your plugin by hooking into the runtime configuration. Resources.groovy is ignored in plugins.

Resources