Where do I place my templates for Blog-related mail notifications in Liferay 7.0? - liferay-7

The documentation states that I can configure the liferay server to use my own templates for the email messages. Specifically, if I add these properties to a portal-ext-env.properties in $CATALINA_BASE/conf/liferay:
blogs.email.entry.added.enabled=true
blogs.email.entry.added.subject=${resource:com/liferay/portlet/blogs/dependencies/email_entry_added_subject.tmpl}
blogs.email.entry.added.body=${resource:com/liferay/portlet/blogs/dependencies/email_entry_added_body.tmpl}
Liferay will supposedly use the templates in the specified paths (com/liferay/portlet/blogs/dependencies/email_entry_added_subject.tmpl and com/liferay/portlet/blogs/dependencies/email_entry_added_body.tmpl). The thing is, it's not very clear what these paths are relative to. Are these files relative to $CATALINA_BASE? For example, would the above configuration result in Liferay looking up $CATALINA_BASE/com/liferay/portlet/blogs/dependencies/email_entry_added_body.tmpl for creating the body of an email message? If this is not the case, where does Liferay lookup templates for Blog-related email messages?

After some digging, I've found that you place the templates in the $CATALINA_BASE/webapps/ROOT/WEB-INF/classes folder. Paths that you reference in the properties (e.g. blogs.email.entry.added.body=${resource:com/liferay/portlet/blogs/dependencies/email_entry_added_body.tmpl}) are relative to the aforementioned classes folder.
So, if I wanted Liferay to use a template file in the ff. relative path: org/foo/my_email_entry_added_body.tmpl, I would do two things:
Place the file in $CATALINA_BASE/webapps/ROOT/WEB-INF/classes/org/foo/my_email_entry_added_body.tmpl.
Add the following line to $CATALINA_BASE/portal-ext-env.properties: blogs.email.entry.added.body=${resource:org/foo/my_email_entry_added_body.tmpl}.
I consulted my co-worker and got a better understanding of why this is. The architecture of a Liferay application is such that it comes bundled with a Tomcat server. According to the documentation, WEB-INF/classes is a directory that a web app deployed to a Tomcat server looks up for classes and resources:
A class loader is created for each web application that is deployed in a single Tomcat instance. All unpacked classes and resources in the /WEB-INF/classes directory of your web application, plus classes and resources in JAR files under the /WEB-INF/lib directory of your web application, are made visible to this web application, but not to other ones.
Specifically, this folder is high in priorty in the web app's classpath.
When you see Liferay code similar to ${resource:path/to/foo}, it's looking up resources in its classpath. One of the paths in that classpath is WEB-INF/classes. Hence, if path/to/foo is placed in WEB-INF/classes, Liferay will find path/to/foo there.

Related

Can't I use subfolders in WEB-INF/lib?

I'm doing some clean-ups in a GWT (no maven) project. It has a lot of jars added in WEB-INF/lib. I know the purpose of those jars (for example for REST service - luckily it's documented) so I wanted to put them in appropriate subfolders for nicer look.
After re-adding them to build path (as now they are in subfolders) I tried to run SuperDevMode and got multiple warnings:
Server class 'X' could not be found in the web app, but was found on the system classpath
and some errors like:
Cannot find a default implementation of the HK2 ServiceLocatorGenerator
When I put those jars back in WEB-INF/lib (without subfolders) and re-add to build path everything runs just fine.
My question is: can't/should't I use subfolders in WEB-INF/lib? If so, why?
Server class loader is programmed to look only into WEB-INF/lib, not other folder nor subfolders.
I strongly suggest to get into the maven world, it has a steep learning curve but it will assure to your project a solid foundation to grow on. Another big plus of Maven is that it can automatically pick up the latest security patch of your libraries (Equifax, anyone?).
Extract from the Apache Tomcat 7 Docs:
WebappX — A class loader is created for each web application that is deployed in a single Tomcat instance. All unpacked classes and resources in the /WEB-INF/classes directory of your web application, plus classes and resources in JAR files under the /WEB-INF/lib directory of your web application, are made visible to this web application, but not to other ones.

Setting up proxy filter for all application on WebSphere Application Server [duplicate]

I want to register filter class for all web application in websphere; Tipically in tomcat I specify filter in /conf/web.xml. How can I do this in Websphere 8.5.
Also what is the common library (lib folder) in websphere. The filter class is in jar file and I want to put that jar file in websphere server lib directory.
-Thanks
Unfortunately there is no easy way to do it in WebSphere. It was already discussed here - Global Filter for all Web Applications
WebSphere solution involves creating custom listener and programmaticaly attach filters. You can find sample solution and description here - Adding a servlet filter to all web applications
What is the common library (lib folder) in Websphere?
You can put your jar to WebSphere\AppServer\lib\ext directory to be shared by all profiles, servers and apps, or create a shared library via web console Environment > Shared libraries and attach it to the specific server or application.

CQ5 - Separate out a servlet's business logic into a standalone bundle

I am new to java, osgi, bundles, cq5 console etc..
Can someone please point me to a tutorial or a starting point from where I can learn how to do what I am trying to achieve.
Basically we have common search functionality in 3-4 CQ5 websites, all of which reside on a single cq instance. This same functionality is implemented in all websites as a servlet and is called from client side using javascript. Redundant code....
We would like to:
a) take this servlet's code out from all the websiteName-core bundles where it resides repeatedly as of now.
b) create a single separate standalone installable OSGI bundle which only contains a servlet.
Then we would like to call this single separated out bundle from all our CQ5 websites's client side.
Aprt from code redundancy, we wish to make this common search bundle shippable so that other development teams can use it in their projects by just installing it in their console and calling the servlet.
Long story short. I want to create an OSGI bundle that has a servlet.
I wish to have an understanding of the whole game here and would prefer to get a tutorial link that explains it from start to end.
You can start by turning the search code into a separate maven multi module project.The archetype and instructions for creating one can be found on adobe's documentation site (link)
The maven multimodule project will have two module's Bundle and content. Bundle will hold all the servlets, OSGI services and back-end stuff. The content module will have all the UI and authoring related stuff like templates and components. It maps to the repository on the CQ server. The UI nodes are serialized and stored on flat file systems as XML documents.
Since it is a maven project on it's own, it's dependencies will be self contained. In the bundle module add the search servlet and all the required classes. The compiled package of this project will be shippable.
As long as the package is installed in the server, any other website will be able to make calls to it.
Servlets in sling are implemented as OSGI services of javax.servlet.Servlet class. Any exported service of the Servlet class will be recognized by the sling servlet resolver, You can get more details of it at this link
Sharath Madappa's answer is correct if you want to create a set of related bundles and distribute them as a CQ content package.
If you just want to create a single bundle to package some OSGi services (including servlets) you just need to build the bundle jar with the required metadata. The Apache Sling GET servlets bundle is a good example of that.

Technical details of serve modules without publishing in Eclipse WTP and Tomcat?

Eclipse's Web Tools Platform (WTP) allows you to configure Tomcat to "Server modules without publishing":
Web content will be served directly from the "WebContent" folder of the Dynamic Web Project. A customized context is used to make the project's dependencies available in the Web application's classloader.
In a 5 step process (just joking, you pick the # of steps), what happens technically and where are the files that Eclipse generates? I did notice that Eclipse generated a org.eclipse.jst.server.tomcat.runtime.70.loader.jar file in the Tomcat lib directory.
The idea is to serve a web application directly from the scattered directory structure of the development workspace, without packaging modules into JARs which then end up in WEB-INF/lib in a WAR.
The main benefits are:
You don't need to build archives.
When you change a resource in your workspace, the change is reflected in the running webapp without redeploying the webapp or restarting the server.
With Servlet 3.0, web resources may also be bundled in library JARs in META-INF/resources, so classes and resources may come from multiple workspace directories.
Tomcat 7.0 supports a VirtualWebappLoader and a VirtualDirContext to configure a web application based on a collection of scattered resource and class directories.
To serve your web app directly from your Eclipse workspace, WTP generates a suitable Tomcat configuration matching your project structure
in $WORKSPACE/.metadata/.plugins/org.eclipse.wst.server.core/tmp1/conf/server.xml
For some reason, WTP does not directly use the Tomcat loader and context implementations but has its own WtpDirContext and WtpWebappLoader which are slightly different but similar. (I believe this approach is older than the current solution in Tomcat. There is some special logic for TLD scanning - I'm not sure if this is still required with the latest Tomcat versions.) These helper classes are contained in the org.eclipse.jst.server.tomcat.runtime.70.loader.jar you noticed.
Without Serve modules without publishing, when you change a web resource in META-INF/resources in a library module, this change will not be directly visible in the running application after reloading the current page in the browser.

How can you develop bottom-up JAX-WS web services referencing classes contained in separate jar files?

I am developing a Java EE 6 bottom-up JAX-WS to expose an EJB3.1 stateless session bean. The web service in a WAR is failing to install on deployment because it references an external jar (or shared library) which one can assume is not loaded yet.
The common suggestion is to include the jars in the /lib folder, which does fix the issue, however the jars need to remain in this external shared library location and NOT in the ear file, because they amount to 30MB.
What are some techniques to get around this issue in a Websphere (WAS v.8) environment or any server environment.
Some suggestions I have found include:
1. define classpath in META-INF file.
2. define the resources in deployment.xml
3. alter class loading order
4. (from ibm) In the case where the jars are part of a Shared Library configured on WebSphere Application Server, then a User Library must be used to configure the project for development before generating the WebService.
However, I have been unsuccessful to find any help online in these areas. Is there another technique or does anyone know anything about accomplishing this? Thanks in advance.
EDIT: If I specify the libraries in the META-INF using class-path, they are loaded before extensions, shared libraries..etc, but they are still loaded after the WAR which is not good. Again, this isn't a runtime issue because the web services are created at deployment on the fly.
I submitted a ticket to IBM. The libraries referenced by the web service are needed during deployment and must be bundled into the Ear in some fashion. I threw them in the web-inf/lib folder. However, if the referenced libraries then depend on additional libraries, these can be placed in the Shared Libraries. Seems odd to me too, but let's all just admit "shared libraries" are a hack anyways.
If you still have issues, just make sure your class loading is set to parent_last.