Foren

How to fix a bug in portlet source code?

thumbnail
Jan Beran, geändert vor 8 Jahren.

How to fix a bug in portlet source code?

Junior Member Beiträge: 44 Beitrittsdatum: 30.06.15 Neueste Beiträge
Hello everybody

I ran into a problem while using the knowledge base portlet. I think I found a bug that prevents me from using the portlet REST service. More about the issue here.
I tracked the bug in the portlet source code in one of the .java files. It can be fixed be two lines of code. But, how do I compile the fixed portlet?

When I try the "plugin extending a plugin" approach, the portlet is compiled but no changes to its behaviour are made. Maybe I did something wrong here. Maybe fixing the .java file only is not enough?

OK, I thought I will start from point 0 and downloaded the portlet source master from GitHub. But, to my surprise, when I try to compile the source, it fails and report 46 bugs in the code. How is that possible? Did I download some work in progress version of the code?

I am now in the corner and all out of ammo. Please, how do I fix a portlet source code myself? If you don't help, I will have to upload hundreds of knowledge base articles to my portal manually. That will make me one sad codemonkey.

Please, before you respond, consider that I am not a Liferay, nor java developer and had exactly 0 experience with development only two weeks ago. I am actually not even a programmer, but this is what I have to do for my job.

Thanks in advance, any advice is much appreciated.
thumbnail
Alexey Kakunin, geändert vor 8 Jahren.

RE: How to fix a bug in portlet source code?

Liferay Master Beiträge: 621 Beitrittsdatum: 07.07.08 Neueste Beiträge
What we do in our case:
* Get portlets source from github: https://github.com/liferay/liferay-plugins/tree/6.2.x/ - please be sure you checking our right branch
* Create own branch for fixing specific problem
* Fix it
* Build it (it is standard SDK environment)
* Optionally you can do pull request back to Liferay repository (and point to this request in bug report).

Knowledge Base portlet you can find here: https://github.com/liferay/liferay-plugins/tree/6.2.x/portlets/knowledge-base-portlet
thumbnail
David H Nebinger, geändert vor 8 Jahren.

RE: How to fix a bug in portlet source code?

Liferay Legend Beiträge: 14915 Beitrittsdatum: 02.09.06 Neueste Beiträge
Um, actually no, not what Alexey says.

You should follow the "plugin extending a plugin" concept to create your own KB portlet that extends the canned one.

If you follow Alexey's path you're committing yourself to maintaining the KB portlet going forward.

If you do the "plugin extending a plugin" concept, you are only committing to managing the one override class that you're concerned about. The "parent" KB plugin can be downloaded when it has been updated, you rebuild your extension and you're done.

Downloading from github is precarious because github is a source repository, not a build repository. Development is ongoing for LR7 and quite probable that all code has been touched.

If you do the "plugin extending a plugin" concept you start from a built and "working" version of the portlet instead of trying to find and fix code that would work in your environment.
thumbnail
Jan Beran, geändert vor 8 Jahren.

RE: How to fix a bug in portlet source code?

Junior Member Beiträge: 44 Beitrittsdatum: 30.06.15 Neueste Beiträge
Thanks for the replies. I actually tried both approaches and failed at both.

So, to get the "plugin extending a plugin" right, suppose I have the portlet installed in my portal. What files do I need to fix for the change to take effect? Because fixing the .java files and merging them with the original war has no effect on the portlet function.
Do I have to compile it to a .class file and then merge it?

Thanks for your replies.
thumbnail
David H Nebinger, geändert vor 8 Jahren.

RE: How to fix a bug in portlet source code?

Liferay Legend Beiträge: 14915 Beitrittsdatum: 02.09.06 Neueste Beiträge
First the original should be undeployed.

When you say you failed at the "plugin extending a plugin" approach, what do you mean? Was there an error? How was it broken? Are you using Maven or the SDK?
thumbnail
Jan Beran, geändert vor 8 Jahren.

RE: How to fix a bug in portlet source code?

Junior Member Beiträge: 44 Beitrittsdatum: 30.06.15 Neueste Beiträge
I did the following steps:

1) Install Eclipse, Liferay IDE, Liferay SDK and Ant, set up all dependencies and properties
2) Undeploy the KB portlet from portal
3) Using Eclipse, create a new "empty" portlet named Knowledge Base
4) In the SDK/portles/knowledge-base-portlet/ delete all files and leave only build.xlm and an empty docroot folder.
5) Add line <property name="original.war.file" value="knowledge-base-portlet-6.2.0.4.war"/> to the build.xml
6) To the SDK/portlets/knowledge-base-portlet/ folder, add the original KB war file.
7) To the same folder, copy the "fixed" files. I only added two lines of harmless code to the KBArticleLocalServiceImpl.java This file was copied with the folder structure of the original portlet.
8) In command line navigated to the knowledge-base-portlet folder and execute "ant merge" command
9) I get this message:
merge:
    [mkdir] Created dir: C:\Users\K1_Adm\Desktop\Liferay-SDK\portlets\knowledge-base-portlet\tmp
    [mkdir] Created dir: C:\Users\K1_Adm\Desktop\Liferay-SDK\portlets\knowledge-base-portlet\tmp\WEB-INF\classes
    [mkdir] Created dir: C:\Users\K1_Adm\Desktop\Liferay-SDK\portlets\knowledge-base-portlet\tmp\WEB-INF\lib
    [unzip] Expanding: C:\Users\K1_Adm\Desktop\Liferay-SDK\portlets\knowledge-base-portlet\knowledge-base-portlet-6.2.0.4.war into C:\Users\K1_Adm\Desktop\Liferay-SDK\portlets\knowledge-base-portlet\tmp
     [copy] Copying 13 files to C:\Users\K1_Adm\Desktop\Liferay-SDK\portlets\knowledge-base-portlet\tmp

But, contrary to the developers guide, no war file was created in the /dist folder. Also, the portlet files were unzipped to the tmp folder, but these are the original files, not the fixed ones. If I execute "ant merge" again, nothing happens.

10) Replace the the KBArticleLocalServiceImpl.java file in the tmp folder with the fixed one.
11) Execute "ant war". I get this:
war:
     [copy] Copying 5 files to C:\Users\K1_Adm\Desktop\Liferay-SDK\portlets\knowledge-base-portlet\docroot\WEB-INF\lib
     [copy] Copying 5 files to C:\Users\K1_Adm\Desktop\Liferay-SDK\portlets\knowledge-base-portlet\tmp
     [echo] Loading jar:file:/C:/Users/K1_Adm/Desktop/Liferay/Tomcat/webapps/ROOT/WEB-INF/lib/portal-impl.jar!/system.properties
     [echo] Loading jar:file:/C:/Users/K1_Adm/Desktop/Liferay/Tomcat/webapps/ROOT/WEB-INF/lib/portal-impl.jar!/portal.properties
     [echo] Parsed C:/Users/K1_Adm/Desktop/Liferay-SDK/portlets/knowledge-base-portlet/docroot/css/main.css in 3744 ms
     [copy] Copying 1 file to C:\Users\K1_Adm\Desktop\Liferay-SDK\portlets\knowledge-base-portlet\tmp
      [zip] Building zip: C:\Users\K1_Adm\Desktop\Liferay-SDK\dist\knowledge-base-portlet-6.2.0.1.war

this time, the war file is created in the /dist folder.

12) Move the war file to the /deploy folder of the portal.
13) Start the Liferay portal. And this where things are starting to get hairy.

Previously, the portlet was deployed successfully, but my changes did not took effect. It was still bugged, despite the KBArticleLocalServiceImpl.java file including my changes.
Now (since I was reenacting the above steps as I wrote this) it for some reason acted differently. The portlet failed to deploy. It was visible in the app manager, but its functions were not present in the portal. I got these errors during deploy:

20:07:25,175 ERROR [localhost-startStop-2][HotDeployImpl:230] com.liferay.portal.kernel.deploy.hot.HotDeployException: Error registering portlets for knowledge-base-portletknowledge-base-portletcom.liferay.portal.kernel.deploy.hot.HotDeployException: Error registering portlets for knowledge-base-portletknowledge-base-portlet
        at com.liferay.portal.kernel.deploy.hot.BaseHotDeployListener.throwHotDeployException(BaseHotDeployListener.java:46)
        at com.liferay.portal.deploy.hot.PortletHotDeployListener.invokeDeploy(PortletHotDeployListener.java:128)
        at com.liferay.portal.deploy.hot.HotDeployImpl.doFireDeployEvent(HotDeployImpl.java:227)
        at com.liferay.portal.deploy.hot.HotDeployImpl.fireDeployEvent(HotDeployImpl.java:96)
        at com.liferay.portal.kernel.deploy.hot.HotDeployUtil.fireDeployEvent(HotDeployUtil.java:28)
        at com.liferay.portal.kernel.servlet.PluginContextListener.fireDeployEvent(PluginContextListener.java:164)
        at com.liferay.portal.kernel.servlet.PluginContextListener.doPortalInit(PluginContextListener.java:154)
        at com.liferay.portal.kernel.util.BasePortalLifecycle.portalInit(BasePortalLifecycle.java:44)
        at com.liferay.portal.kernel.util.PortalLifecycleUtil.register(PortalLifecycleUtil.java:74)
        at com.liferay.portal.kernel.util.PortalLifecycleUtil.register(PortalLifecycleUtil.java:58)
        at com.liferay.portal.kernel.util.BasePortalLifecycle.registerPortalLifecycle(BasePortalLifecycle.java:54)
        at com.liferay.portal.kernel.servlet.PluginContextListener.contextInitialized(PluginContextListener.java:116)
        at org.apache.catalina.core.StandardContext.listenerStart(StandardContext.java:4939)
        at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5434)
        at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150)
        at org.apache.catalina.core.ContainerBase.addChildInternal(ContainerBase.java:901)
        at org.apache.catalina.core.ContainerBase.addChild(ContainerBase.java:877)
        at org.apache.catalina.core.StandardHost.addChild(StandardHost.java:633)
        at org.apache.catalina.startup.HostConfig.deployDirectory(HostConfig.java:1113)
        at org.apache.catalina.startup.HostConfig$DeployDirectory.run(HostConfig.java:1671)
        at java.util.concurrent.Executors$RunnableAdapter.call(Unknown Source)
        at java.util.concurrent.FutureTask.run(Unknown Source)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
        at java.lang.Thread.run(Unknown Source)
Caused by: java.lang.NoClassDefFoundError: com/sun/syndication/io/FeedException
        at java.lang.Class.getDeclaredMethods0(Native Method)
        at java.lang.Class.privateGetDeclaredMethods(Unknown Source)
        at java.lang.Class.getDeclaredMethod(Unknown Source)
        at com.liferay.portal.javadoc.JavadocManagerImpl.parseJavadocMethod(JavadocManagerImpl.java:272)
        at com.liferay.portal.javadoc.JavadocManagerImpl.parseDocument(JavadocManagerImpl.java:201)
        at com.liferay.portal.javadoc.JavadocManagerImpl.load(JavadocManagerImpl.java:65)
        at com.liferay.portal.kernel.javadoc.JavadocManagerUtil.load(JavadocManagerUtil.java:35)
        at com.liferay.portal.deploy.hot.PortletHotDeployListener.doInvokeDeploy(PortletHotDeployListener.java:481)
        at com.liferay.portal.deploy.hot.PortletHotDeployListener.invokeDeploy(PortletHotDeployListener.java:125)
        ... 23 more
Caused by: java.lang.ClassNotFoundException: com.sun.syndication.io.FeedException
        at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1714)
        at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1559)
        ... 32 more


I would be grateful for any further advice.
thumbnail
David H Nebinger, geändert vor 8 Jahren.

RE: How to fix a bug in portlet source code?

Liferay Legend Beiträge: 14915 Beitrittsdatum: 02.09.06 Neueste Beiträge
The docroot folder is used like the _diffs folder for themes. Your overrides should go in there, so basically the only thing you'll have in your docroot folder is WEB-INF/src and your source overrides go in the appropriate package.

At build time you should end up with a docroot/WEB-INF/classes with your compiled class and then the merge should take care of the rest.

The class not found exception is from the missing rome.jar. Make sure the liferay-plugin-package.properties file still has the rome.jar as a dependency.
thumbnail
Jan Beran, geändert vor 8 Jahren.

RE: How to fix a bug in portlet source code?

Junior Member Beiträge: 44 Beitrittsdatum: 30.06.15 Neueste Beiträge
Hi David

Thanks again for your reply. I have finally succeeded in compiling the modified war file. But deploying it to the portal has blown it to pieces. The portal has failed to startup with following error:

09:32:50,781 ERROR [http-bio-8080-exec-5][status_jsp:753] javax.servlet.ServletException: com.liferay.portal.kernel.portlet.PortletContainerException: com.liferay.portal.kernel.portlet.PortletContainerException: javax.servlet.ServletException: java.lang.StackOverflowError


The webpage in the browser displays "Internal server error" message, and whenever I refresh it, the following starts to scroll in Tomcat console (note: these three lines repeat so many times, that I cannot see the top line of the error message):

        at com.liferay.portal.kernel.servlet.filters.invoker.InvokerFilter.doFilter(InvokerFilter.java:119)
        at com.liferay.portal.kernel.servlet.filters.invoker.InvokerFilterChain.processDoFilter(InvokerFilterChain.java:204)
        at com.liferay.portal.kernel.servlet.filters.invoker.InvokerFilterChain.doFilter(InvokerFilterChain.java:109)


Removing the knowledge-base-portlet from WebApps folder allows the portal to startup.

Does this mean, that the portlet was compiled wrong, or is there some problem in the source? Any ideas what is wrong would be much appreciated, thanks.

EDIT: I don't know if it helps finding the issue, but I cought these two little buggers with screenshots.

SEVERE: Servlet.service() for servlet jsp threw exception
java.lang.StackOverflowError
at java.util.HashMap.hash(Unknown Source)
at java.util.HashMap.get(Unknown Source)
at org.apache.catalina.connector.Request.getAttribute(Request.java:945)
at org.apache.catalina.connector.RequestFacade.getAttribute(RequestFacade.java: 284)
at org.apache.catalina.core.ApplicationHttpRequest.getAttribute(ApplicationHttpRequest.java:221)
at org.apache.catalina.core.ApplicationHttpRequest.getAttribute(ApplicationHttpRequest.java:221)
at org.apache.catalina.core.ApplicationHttpRequest.getAttribute(ApplicationHttpRequest.java:221)
at org.apache.catalina.core.ApplicationHttpRequest.getAttribute(ApplicationHttpRequest.java:221)
at javax.servlet.ServletRequestWrapper.getAttribute(servletRequestWrapper.java:76)
at com.liferay.portal.kernel.portlet.RestrictPortletServletRequest.getAttribute(RestrictPortletServletRequest.java:63)
at javax.servlet.ServletRequestWrapper.getAttribute(ServletRequestWrapper.java:76)
at javax.servlet.ServletRequestWrapper.getAttribute(ServletRequestWrapper.java:76)
at com.liferay.portal.servlet.NamespaceservletRequest.getAttribute(NamespaceservletRequest.java:78)
at com.liferay.portal.kernel.servlet.filters.Invoker.InvokerFilter.getURI(InvokerFilter.java:261)
at com.liferay.portal.kernel.servlet.filters.Invoker.InvokerFilter.doFilter(InvokerFilter.java: 72)
at com.liferay.portal.kernel.servlet.filters.Invoker.InvokerFilterChain.processDoFilter(InvokerFilterChain.java:204)
at com.liferay.portal.kernel.servlet.filters.Invoker.InvokerFilterChain.doFilter(InvokerFilterChain.jeue:109)
at com.liferay.portal.kernel.servlet.filters.invoker.InvokerFilter.doFilter(InvokerFilter.java:119)



15:11:01 ,343 ERROR [http-bio-SOSO-exec-3][status_jsp : 753] javax.servlet.ServletException: com.liferay.portal.kernel.portlet.PortletContainerException :
com.liferay.portal.kernel.portlet.PortletContainerException: javax.servlet.5ervletException : java.lang.StackOverflowError
Exception in thread ''http-bio-8080-exec-4'' Exception in thread '' http-bio-8080-exec-S'' java.lang.StackOverflowError
at com.liferay.portal.kernel.util.Validator.isNull(Validator.java:1089)
at com.liferay.portal.kernel.util.StringUtil.split(StringUtil.java :3030)
at com.liferay.portal.kernel.util.StringUtil.split(StringUtil.java:3177)
at com.liferay.portal.kernel.util.HttpUtil.normalizePath(HttpUtil.java:213)
at com.liferay.portal.kernel.servlet.filters.invoker.InvokerFilter.getURI(InvokerFilter.java:275)
at com.liferay.portal.kernel.servlet.filters.invoker.InvokerFilter.doFilter(InvokerFilter.java:72)
at com.liferay.portal.kernel.servlet.filters.invoker.InvokerFilterChain.processDoFilter(InvokerFilterChain.java:204)
at com.liferay.portal.kernel.servlet.filters.invoker.InvokerFilterChain.doFilter(InvokerFilterChain.java:109)
at com.liferay.portal.kernel.servlet.filters.invoker.InvokerFilter.doFilter(InvokerFilter.java:119)
thumbnail
Jan Beran, geändert vor 8 Jahren.

RE: How to fix a bug in portlet source code? (Antwort)

Junior Member Beiträge: 44 Beitrittsdatum: 30.06.15 Neueste Beiträge
I DID IT. I successfully compiled the portlet, deployed it and it works!!!

So, turns out that the latest butch of bugs originated from the compilation process. When I placed only the modified .java file in the docroot folder, if was getting compilation errors that said I am missing some classes and dependencies. I figured I have to put those to the docroot folder too. To save time with copying one missing reference after other, I just copied the whole deployed Knowledge base folder. That was wrong.
Yes, I had all the dependencies, but I was getting some weird errors during build. Those were corrected mainly by compiling for java 1.7. The portlet got compiled but after deployment blew the portal to pieces.
After many long hours of compiling, deploying and swearing, I came to the solution: Only include the /classes and /src folders in the WEB-INF directory. Then I was able to compile for java 1.8, deploy the portlet and get it running as expected. The change to the source code has taken effect and Knowledge base is working as intended.

Thanks you David for your advice. I helped. I would just recommend to correct the documentation at Liferay wiki. Now excuse me while I engage the victory jig emoticon
Dimas Purdinanto, geändert vor 8 Jahren.

RE: How to fix a bug in portlet source code?

Junior Member Beiträge: 29 Beitrittsdatum: 11.08.15 Neueste Beiträge
Hi Jan,

I'd like to modify web-form portlet, would you walk through me on how to do it?

Thank you
Dimas
thumbnail
Jan Beran, geändert vor 8 Jahren.

RE: How to fix a bug in portlet source code?

Junior Member Beiträge: 44 Beitrittsdatum: 30.06.15 Neueste Beiträge
Hi Dimas

Pretty much all I know is written above. To summarize the process, try to follow these step:

1) Install Java developement kit, Eclipse (with Liferay plugin), Apache Ant and Liferay SDK
2) Using Eclipse, create a new portlet - a folder ../Liferay SDK/Portlets/newportlet
3) Copy the original web-form portlet war file to this folder.
4) Change the Build.xml file, as outlined in the "plugin extending a plugin" approach. Watch out for the whitespaces.
5) Change any of the source files of the plugin and copy them to the docroot folder, including the folder structure of the original portlet. Also copy the JAVA class files.
6) Rebuild the portlet using Ant and deploy.

Your mileage may wary. It wasnt easy for me the first time, and I sadly dont remember all the little tweaks I had to do along the way. I remember I had to change some settings in the build.properties file.

Hope this helps.
thumbnail
James Falkner, geändert vor 8 Jahren.

RE: How to fix a bug in portlet source code?

Liferay Legend Beiträge: 1399 Beitrittsdatum: 17.09.10 Neueste Beiträge
Jan Beran:
Hi Dimas

Pretty much all I know is written above. To summarize the process, try to follow these step:
...

Hope this helps.


Hey Jan! Congratulations on getting it to work! And thanks even more for documenting your process. It is community members like you that make our little corner of the universe a little brighter.

Was it actually a bug in the KB source? Would you be willing to contribute that back so future devs don't run into the same bug?
thumbnail
Jan Beran, geändert vor 8 Jahren.

RE: How to fix a bug in portlet source code?

Junior Member Beiträge: 44 Beitrittsdatum: 30.06.15 Neueste Beiträge
Hi James

I have already reported the issue here.
I have also provided the code fix in there.

Also, would it be possible to fix the documentation here? The step 4) is wrong, as my comment suggests.