How to override property "sites.email.membership.reply.body" in liferay - hook

I want override the following properties in my portal-ext.properties:
sites.email.membership.reply.subject=com/liferay/portlet/sites/dependencies/email_membership_reply_subject.tmpl
sites.email.membership.reply.body=com/liferay/portlet/sites/dependencies/email_membership_reply_body.tmpl
sites.email.membership.request.subject=com/liferay/portlet/sites/dependencies/email_membership_request_subject.tmpl
sites.email.membership.request.body=com/liferay/portlet/sites/dependencies/email_membership_request_body.tmpl
to something like this:
sites.email.membership.reply.subject=com/krishna/email_membership_reply_subject.tmpl
sites.email.membership.reply.body=com/krishna/email_membership_reply_body.tmpl
sites.email.membership.request.subject=com/krishna/email_membership_request_subject.tmpl
sites.email.membership.request.body=com/krishna/email_membership_request_body.tmpl
I have done this in EXT, i.e. I have created the package: ext-impl/src/com/krishna/ in EXT-plugin and it works fine, but I am not able to do this in a hook or portlet. Why? Because its giving me exception:
java.io.IOException: Unable to open resource in class loader com/krishna/email_membership_request_subject.tmpl
So, my question: Is there a way to do it in hook or portlet or only EXT can be used?
Thanks

This can be done only in an EXT plugin. Because of the following two reasons:
Hooks can be advantageous to override few properties/services but not all. This particular property is not supported by hooks.
This is definitely not possible with portlets, as you already are facing class loading issues. As portal-impl.jar is located inside the ROOT/WEB-INF/lib of liferay and your portlet doesn't have access to it.
So EXT plugin is the only way.

Related

Why is micronaut invoking the wrong controller method?

I have a micronaut API like this:
#Get("/")
List<Club> listClubs()
#Get("/{id}")
Club show(Long id)
In my unit test, when I invoke the show method, the listClubs() method is actually getting invoked, instead.
Why is this happening?
Details:
Thinking that my URL mappings must be wrong, I started debugging into Netty to try to understand how the framework constructs URLs.
In HttpClientIntroductionAdvice, the context shows the API method like this:
Club show(Long param0)
The interceptor is setting param0 in the parameter map, which doesn't match the actual parameter name of my method. When the URI template is expanded, this causes the ID to get dropped (thus the URI becomes / instead of /1).
I am trying to follow this example:
https://github.com/alvarosanchez/micronaut-workshop/tree/master/ex02/solution/clubs
There is one important different in my project, which is that the endpoint is set at "/club" instead of at "/":
#Controller("/club")
#Client("/club")
I am using a diff tool to compare my project to the sample, but I am struggling to find any other difference (besides package name changes).
Why is this happening? What should I be looking for?
Thanks
Update:
Tested the target endpoint with the browser - looks fine.
Gradle clean does not resolve the issue.
I switched from debugging the Application class with IntelliJ to using "gradlew run" and in the process, I made a change to build.gradle (adding JVM properties pass-through from the gradle CLI). I also played with enabling/disabling the annotation processor in the IDE.
(note: In the previous project, I enabled annotation processing as soon as I imported into the IDE. On this project, I didn't enable it until I started having issues.)
I think the build.gradle alteration caused the problem to go away. Since the issue shows up unreliably, it's hard to tell for certain if this is the change that caused it to be fixed.

Sending custom objects across portlets in liferay

I'm having serious issues trying to send share custom objects between portlets in liferay. I have a Hook Plugin, with a servlet filter, which loads an object of Type MyCustomClass and inserts it into the request object as a parameter.
When i try to read this object in a portlet's render() i get a ClassCastException, though i am casting the object to the same class.
I understand that liferay plugins have different contexts, and i already tried to change the classloader before loading the object in the bean and portlet like this:
ClassLoader portalcl = PortalClassLoaderUtil.getClassLoader();
ClassLoader currentcl = Thread.currentThread().getContextClassLoader();
Thread.currentThread().setContextClassLoader(portalcl);
//do my stuff
Thread.currentThread().setContextClassLoader(currentcl);
however, it did not solved the problem, and the only way i found to solve the problem is to serialize the object into a json string, and deserialize it whenever i need it.
Isn't this kinda lame ? Does anyone know a better solution ?
Regards, DS
It sounds like the main problem you're seeing is that two different class loaders are loading the class which techncally makes them different classes (which it seems like you've already determined).
I haven't used LifeRay much but this has been a problem I've seen on other platforms as well. We were using WebSphere and solved this problem by putting the common MyCustomClass into a shared library that was on the server classpath. This way the server will load the class and make it available to all applications on the server through the server's single classloader. If you let each application load the class then you'll keep seeing this exception.

ClassLoader - Loading and saving data

Hopefully someone can help me with this.
It is my understanding that using a ClassLoader is the most reliable way to load in content.
public class Pipeline{
public static URL getResource(String filename) {
return ClassLoader.getSystemResource(filename);
}
public static InputStream getResourceAsStream(String filename) {
return ClassLoader.getSystemResourceAsStream(filename);
}
}
If you had a file at "[jar bundle]/resources/abc.png" ..You would load it by:
URL url = Pipeline.getResource("resources/abc.png");
Loading is simple.
Saving is what's getting me.
I have a program that collects data while running, saves that data on exit, and then loads the data back in next time and keeps adding to it.
Easiest solution I think would be to save back into the jar bundle so that ClassLoader can get at them. Is this even possible? Or recommended?
I don't mind having my resources outside of the jar, just as long as I don't have to resort to 'File' to get at them and save to them. (Unless it can be done cleanly)
folder/application.jar
folder/resources/abc.png
If you could ../ back one from where the ClassLoader is looking it would be easy to cleanly get data from the directory that actually contains the jar file
Pipeline.getResource("../resources/abc.png");
Any ideas?
This isn't really what class loaders are meant for. Loading resources from the class loader is meant so that you can bundle up your application as one package and components can read each other without worrying about how the system you're deploying to is setup.
If the file in the JAR is meant to be changed by the app, then it isn't part of the app and thus probably shouldn't be in the JAR.
I don't have a lot of context on your app, but hopefully my suggestion will be valid for your situation.
I recommend setting a requirement in your app that it has a work area to which it is allowed to read and write and accept a configuration setting that specifies where this directory is. Typical ways to do this in Java are with environment variables, system properties or JNDI settings (for container deployments).
Examples:
Tomcat's startup scripts figure out where it is installed and sets a system property called catalina.home and allows you to over-ride it with an environment variable called CATALINA_HOME.
JBoss looks for JBOSS_HOME
Java application servers typically look for JAVA_HOME to find the JDK.

Login Portlet Hook, class not found PwdEncryptor

I create a hook for login portlet.
I have problem with this line of code:
String encPwd = PwdEncryptor.encrypt(password, user.getPassword());
The class PwdEncryptor not found and package com.liferay.portal.security.pwd does not exist
I use a Liferay 6.0.6 plugin to create a hook and i read this:
Developing a CAS (Custom Authentication System)
and:
https://www.liferay.com/es/community/forums/-/message_boards/message/14773767
PwdEncryptor is in portal-impl.jar so it's not visible to plugins. What you could use is PortalClassInvoker to invoke it. If you need example check out com.liferay.portal.kernel.struts.PortletActionInvoker class.
I don't know what to do with this invoker, where to call it or use it.
integrade PwdEncryptor and Crypt.

adding custom methods in Hook environment?

i am adding a new method into CalEventLocalServiceImpl using hook...
my code is ..
public class MyCalendarLocalServiceImpl extends CalEventLocalServiceWrapper {
public MyCalendarLocalServiceImpl(CalEventLocalService calEventLocalService) {
super(calEventLocalService);
// TODO Auto-generated constructor stub
}
public List getUserData(long userId) throws SystemException{
DynamicQuery query=DynamicQueryFactoryUtil.forClass(CalEvent.class)
.add(PropertyFactoryUtil.forName("userId").eq(userId));
List deatils=CalEventLocalServiceUtil.dynamicQuery(query);
return deatils;
}
}
liferay-hook.xml:
<service>
<service-type>
com.liferay.portlet.calendar.service.CalEventLocalService
</service-type>
<service-impl>
com.liferay.portlet.calendar.service.impl.MyCalendarLocalServiceImpl
</service-impl>
</service>
my question is how to use getUserData from jsp file.
Can anybody help me out....
i think u didn't gt my question...i want list of events based on USERID from Calendar ...to achieve this task what i need to do??
I assume getUserData() is not overridden but a new method (can't look up currently). This is not what you can do when overriding a service. Instead you'd have to add a new Service and make it available to the portal.
Remember that a customized ("hooked") jsp is running in the portal classloader, while your overloaded service is running in the hook's classloader. Thus, if you create a new service and make the service.jar available to Liferay (e.g. on the global classpath) you can call it from JSPs. The interface of Liferay services can not be extended through an overloaded service.
In case getUserData() is already in the interface (as I said I can't look up currently), you just need to call the CalendarLocalServiceUtil from your jsp and it will be delegated to your wrapper.
Just to add to Olaf's answer and comments...
if you you want to extend CalEventLocalService service with just "getUsetData" and use it in one jsp than building your own service might be overkill. Simply put your code from "getUserData" in jsp. Otherwise follow Olaf's suggestions.

Resources