Extending ProfileImages servlet in cq5 - osgi

I am trying to extend ProfileImages servlet from /libs/foundation/src/impl/src/main/java/com/day/cq/wcm/foundation/pro file/impl/ProfileImages.java
and bundling as an OSGI service.
I have the following annotations
#Component(immediate=true)
#SlingServlet(
resourceTypes = {"nt:file"},
methods = {"GET"},
selectors = {"adjust","adjust.small"},
extensions = {"res", "jpg", "png", "gif"}
)
I see my service in bundles and Services in OSGI console. However it is not doing as ProfileImages servlet used to do
ProfileImages create the thumbnail if we invoke the following URL
http://mydomain.com:4502/content/dam/geometrixx/portraits/scott_reynolds.jpg.prof.thumbnail.100.100.jpg
If my servlet is invoke, I should get the same response
http://mydomain.com:4502/content/dam/geometrixx/portraits/scott_reynolds.jpg.adjust.small.100.100.jpg
However I am getting is 404 which is from the DefaultGetServlet
It seems that Sling servet is not able to resolve my servlet
One thing I need to know is how to get my service updated in
Apache Sling Servlet Resolverorg.apache.sling.servlets.resolver
My servlet is doing the same thing as the following service in sling servlet resolver
Service ID 843 Types:
org.apache.sling.api.resource.ResourceProvider
Description: ServletResourceProvider for Servlets at
[/libs/foundation/components/primary/nt/file/prof/thumbnail.gif.servl
et, /libs/foundation/components/primary/nt/file/prof.gif.servlet,
/libs/foundation/components/primary/nt/file/prof/thumbnail.res.servle
t, /libs/foundation/components/primary/nt/file/prof.jpg.servlet,
/libs/foundation/components/primary/nt/file/prof.png.servlet,
/libs/foundation/components/primary/nt/file/prof/thumbnail.png.servle
t,
/libs/foundation/components/primary/nt/file/prof/thumbnail.jpg.servle
t, /libs/foundation/components/primary/nt/file/prof.res.servlet]
My service should be listed in sling resolver with id and something like
...../adjust.small.jpg.servlet, ..../adjust.res.servlet
I am using CRXDE web version for development
Is there any configurations I have to do to get my service in over resource resolver?

Your servlet can not be resolved because it is not registered with the Declarative Services Runtime.
The #Component and #SlingServlet annotations are not evaluated at runtime, they are part of the Apache Felix SCR Plugin Project which provides a maven plugin and ant task to create "OSGi Declarative Services" descriptors.
http://felix.apache.org/documentation/subprojects/apache-felix-maven-scr-plugin.html
For registering your Servlet as an OSGi Service an OSGI-INF/serviceComponents.xml file is required.
So I'm afraid you won't get around using a build lifecycle tool to build your OSGi bundle before uploading to CQ5, if you are planning to use the scr annotations.
Else you have to create your service component file manually.

Related

Log4j2 JSP Taglib not working in Spring-boot Embedded Servlet Containers

I have a Spring boot web application which I created using the spring-boot-starter-web artifact. I am using Spring Boot Embedded Servlet Containers features to use the Tomcat embedded server. I am able to run my app in Tomcat embedded mode. I can also create a WAR file of my app and deploy it to a normal installation of Tomcat.
I have one JSP page in which I am using log4j2's JSP taglib tags. On a normal installation of Tomcat the logging from that JSP page works as expected. But when bootRun on the Tomcat embedded server I get the following error
SEVERE: Servlet.service() for servlet [jsp] in context with path [] threw exception [The absolute uri: [http://logging.apache.org/log4j/tld/log] cannot be resolved in either web.xml or the jar files deployed with this application] with root cause
org.apache.jasper.JasperException: The absolute uri: [http://logging.apache.org/log4j/tld/log] cannot be resolved in either web.xml or the jar files deployed with this application
Can this issue be solved?
The problem is occurring because Spring Boot skips log4j-*.jar by default. I've opened an issue to address this.
You can work around the problem by explicitly enabling scanning of the log4j-taglib jar. To do so, you need to add a TomcatContextCustomizer that changes the configuration of the jar scanner:
#Bean
TomcatContextCustomizer log4jTldScanningCustomizer() {
return (context) ->
((StandardJarScanFilter)context.getJarScanner().getJarScanFilter()).setTldScan("log4j-taglib*.jar");
}

JerseyTest and Spring and creating a ServletContext

I'm working on migrating from Jersey 1.16 to Jersey 2.7. I have the application running and working, but I'm having trouble with the tests.
Some things to note:
The application uses Spring and is configured by a class, ApplicationConfiguration.class.
The application does not have a web.xml - the Jersey servlet and filters are configured programmatically.
I am using the jersey-spring3 library.
Related to using the jersey-spring3 library, I have to add a workaround to my onStartup method
// The following line is required to avoid having jersey-spring3 registering it's own Spring root context.
// https://java.net/jira/browse/JERSEY-2038
servletContext.setInitParameter("contextConfigLocation", "");
Here's the issue:
When the test is starting up, SpringComponentProvider, tries to initialize Spring with a dangerous assumption that I can't figure out how to correct - xml based configuration. Looking at the code, the trouble is this block
ServletContext sc = locator.getService(ServletContext.class);
if(sc != null) {
// servlet container
ctx = WebApplicationContextUtils.getWebApplicationContext(sc);
} else {
// non-servlet container
ctx = createSpringContext();
}
Running a JUnit test, ServletContext is null, and createSpringContext is called.
Here's the question:
Is there a way to run a test and specify a ServletContext/ServletContainer?
I believe this issue is covered by https://java.net/jira/browse/JERSEY-2259.
In short: they removed this functionality from Jersey 2.x and are treating it as a Feature Request (instead of regression) so it's not considered a high-priority item.

WAS 8.5 - Can a blueprint managed OSGI service have a reference to a declarative services managed OSGI service?

We use WebSphere 8.5 (NON-Liberty Profile… just straight-up WAS) and we have a Spring 3.2 web app that is accessing an OSGI service which is using the blueprint component model via an SCA service bridge. We did this this way because to our understanding, this was the only way to be able to access the OSGI services layer from within our current architecture. If anyone might know of another/better way, I'm also all-ears on this as well.
From within this blueprint managed service, we'd like to have a reference to another service. This other service(and any service references within it) we'd like to have managed by the declarative services component model.
My question is… is this possible? Does anyone know if this mixing of these two component models from within WAS 8.5 is do-able in any way, shape, or form??
And if it is possible, might anyone be able to point me in the right direction on how to approach this?
Edit - Dec 5th
So the approach I decided to take was to first, build a small proof-of-concept application that uses three different OSGI bundles all using blueprint. Then once I have this working, take one of the blueprint managed services, and attempt to convert it to a ds managed service.
Here's what I've got so far:
I have ran through and created the tutorial located here. I currently have the CounterApp OSGI bundle Application containing the following bundles as application content:
CounterServiceBundle
CounterWebBundle
CounterWorldBundle
As is stated in the tutorial, all of the above are tied together using the blueprint component model via the blueprint.xml files.
So it all breaks down as follows:
From within the doGet method of the CounterWebBundle's CounterServlet I have a Greet service being used in the following manner:
Greet greet;
try {
InitialContext ic = new InitialContext();
greet = (Greet) ic.lookup("osgi:service/"+Greet.class.getName());
String greetText = greet.getText();
String output = "greet.getText()="+greetText;
response.getOutputStream().println(output);
} catch (NamingException e) {
e.printStackTrace(System.out);
}
This "greet" service is defined in the blueprint xml as "GreetBeanService". Now, within its implementation class it has references to two other services, "CounterBean" and "WorldRef".
Here is the blueprint.xml file to clarify:
<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0">
<bean id="CounterBean" class="com.ibm.ws.eba.counter.CounterImpl"
init-method="init"></bean>
<service id="CounterBeanService" ref="CounterBean"
interface="com.ibm.ws.eba.counter.Counter" />
<bean id="GreetBean" class="com.ibm.ws.eba.counter.GreetImpl"
init-method="init">
<property name="counter" ref="CounterBean"/>
<property name="worldBean" ref="WorldRef"/>
</bean>
<service id="GreetBeanService" ref="GreetBean"
interface="com.ibm.ws.eba.counter.Greet" />
<reference id="WorldRef" interface="com.ibm.ws.eba.world.World" />
</blueprint>
So the thing is this:
I'm aiming to convert the "WorldRef" service to a DS managed service with a component.xml file and the following added to the MANIFEST.MF header Service-Component: OSGi-INF/component.xml of the implementation Class, not the API Class if I'm understanding correctly.
Would this be all I would need to do for the conversion? Or do I also need to add an Activator for the Class? Also, would I need to add 'activate' and 'deactivate' methods in the API implementation Class?
Also I'm of the understanding that I have to somehow include the service component runtime, as a separate bundle and include it in the "CounterApp" application, how exactly would I do this? Do I have to create a separate bundle project consisting of the following bundle/jars
org.eclipse.equinox.util
org.eclipse.equinox.ds
org.eclipse.osgi.services
where I would then re-export all of the exported interfaces from all of these jars?
Or do I have to define some sort of service to export that exposes the SCR?
Edit - Dec 6th
I went ahead and created a new DS OSGI bundle/jar containing all of the above mentioned jar files required to provide the equinox DS implementation, then just passed on the exports of each jar in this new bundle. I then added this DS bundle to my CounterApp application and imported each of these DS bundle exports into the bundle containing the WorldRef service.
This is where I appear to be getting hung up:
The OSGI framework is loading the bundle containing the WorldRef service but the service is not being added to the registry, which suggests that the component.xml file defining the service isn't being read, which, intern suggests that the SCR is not running because it is what reads that file to my understanding.
So still stuck on the ability to get the SCR running. I am under a very tight deadline (I know… who isn't, right?

How to use Spring Roo with Apache Wicket?

I have a persistence layer (JPA entity objects) created and managed by Roo. It is in its own project, builds to a jar, and I have used it with a separate Spring MVC 3 web application.
I'd like to use this same Roo persistence project in another web application powered by Apache Wicket. I have seen a couple of the Roo add-ons made for Wicket, but none of them even compile (I'm not the only one to have the issue).
The problem I am encountering is that whenever I try to call one of my Roo entities from within a Wicket Page or component, I get the following exception:
Caused by: java.lang.IllegalStateException: Entity manager has not been injected (is the Spring Aspects JAR configured as an AJC/AJDT aspects library?)
at com.x.domain.UserAccount_Roo_Entity.ajc$interMethod$com_x_domain_UserAccount_Roo_Entity$com_x_domain_UserAccount$entityManager(UserAccount_Roo_Entity.aj:91)
at com.x.domain.UserAccount.entityManager(UserAccount.java:1)
I have configured my application following the Spring+Wicket wiki here: https://cwiki.apache.org/WICKET/spring.html
Does anyone know the 1,2,3 steps to set up a Wicket application to utilize Spring Roo entities? Any help is appreciated. Thanks!
I found this in google code, sounds like its doing exactly what you want http://code.google.com/p/spring-roo-wicket-addon/
I found the solution to my problem. When I ran my wicket webapp using the Maven jetty:run goal, it worked. However, I was trying to start Jetty via Java code:
public class Start {
public static void main(String[] args) throws Exception {
Server server = new Server();
SocketConnector connector = new SocketConnector();
server.start();
}
}
I was not loading the Spring ApplicationContext in this "Start" class. Once I modified this class to load the Spring application context, it worked

Restlet jse2 client resource interface not visible from class loader

I Followed this tutorial for my Restlet server in the Google App Engine: http://wiki.restlet.org/docs_2.0/13-restlet/21-restlet/318-restlet/303-restlet.html It works fine with the GWT client.
Now i'm trying to build a jse2 desktop client with OSGi and Restlet.
The code for the Restlet client in the OSGi bundle stay's the same as the tutorail provided.
When i start the OSGi Felix framework i also start the org.restlet.jar bundle who's exporting the restlet framework packages and i start a bundle with this code given in the toturail:
ClientResource cr = new ClientResource("localhost:8888/contacts/123");
// Get the Contact object
ContactResource resource = cr.wrap(ContactResource.class);
Contact contact = resource.retrieve();
The ContactResoure interface is in the same package as the bundle activator but i still get this strange message: java.lang.IllegalArgumentException: interface nl.nhl.minor.crm.desktop.restlet.ContactResource is not visible from class loader
Is this problem related to OSGi or to Restlet? And how can I solve this problem?
The manifest files for the OSGi bundles are created by the maven bundle plugin.
The correct way of loading a class is easy:
ClientResource cr = new ClientResource("http://127.0.0.1:8888/contacts/123");
Class<ContactResource> clazs = (Class<ContactResource>) cr.getClass().getClassLoader().loadClass("your.package.name.ClassName");
cr.wrap(clazs);
This solution give you a other problem, the class isn't imported by the org.restlet bundle.
See import package without edit the manifest file in org.restlet for my question about that problem.

Resources