Retrolambda and Hippo Cms
This project can only be compiled with the JDK 8 as it makes heavy use of its features: lambdas, default methods and more.
Thanks to Retrolambda, many projects that make use of the new features of JDK 8 can be migrated to JDK7 (and earlier) and therefore also to Android, where primary use is made this tool.
And with this maven plugin you can integrate it into your buildsystem. Here is an example of how to use it. And besides, there is another for Gradle.
Limitations
But there are some well known limitations, which makes the migration of the default method of JDK 8 are not so easy, "must to be backported together, with one execution of Retrolambda".
So by default is disabled in the migration.
When Retrolmambda migrates Default Methods: Default methods are backported by copying the default methods to a companion class (interface name + "$") as static methods, replacing the default methods in the interface with abstract methods, and by adding the Necessary method Implementations to all classes which implement that interface.
Retrolambda (and HippoCms)
Take, for example, the following project.
Suppose that initially have this interface module with the default method.
public interface IconProvider extends IClusterable {
default Component getIcon(final String id, IconSize size) {
return null;
}
}
Retrolambda what makes this class is transformed into this one.
public abstract interface IconProvider2 extends IClusterable {
public abstract Component getIcon(String paramString, IconSize paramIconSize);
}
And implements that method (through the "companion class") in classes that implement the interface, classes in the same module.
Therefore, if not process all child classes that interface module in the past, and will not, so…
public class SearchingSectionPlugin extends RenderPlugin implements IBrowserSection
this in another module, trying to be compiled gives this error
[ERROR] /hippo-cms/perspectives/src/main/java/org/hippoecm/frontend/plugins/cms/browse/section/SearchingSectionPlugin.java:[63,7]
error: SearchingSectionPlugin is not abstract and does not override abstract method getIcon(String,IconSize) in IconProvider
First conclusions
At first, unread well the error message, and without understanding the class hierarchy of the project, I thought it might help this PR
If you want to understand more in detail, here some notes on the Lifecycle of maven. And here on classloading.
Then read more in detail, I thought the problem was that the transformation the interface to abstract … well, i admit this tweet had distracted me from the real problem, because the interfaces are abstract (by default).
And the own Esko Luontola explains why. "8 pre-Java JVMs support only abstract methods in interfaces (the <clinit> method being an exception). Retrolambda code inserts the default method implementing to all classes, JVM 8 thus emulating what does."
Explanation of the real problem
But the problem, in this case, was simply the limitation of the library in multi module projects here and here as also discussed in detail.
A way out by making small manual changes in the code, it would be implementing the method getIcon(String, IconSize) with the default behavior in class the second module.
diff --git a/perspectives/src/main/java/org/hippoecm/frontend/plugins/cms/browse/section/BrowsingSectionPlugin.java b/perspectives/src/main/java/org/hippoecm/frontend/plugins/cms/browse/section/BrowsingSectionPlugin.java
index 99bdb0e..9b34ce1 100644
--- a/perspectives/src/main/java/org/hippoecm/frontend/plugins/cms/browse/section/BrowsingSectionPlugin.java
+++ b/perspectives/src/main/java/org/hippoecm/frontend/plugins/cms/browse/section/BrowsingSectionPlugin.java
@@ -18,6 +18,7 @@
import javax.jcr.Node;
import javax.jcr.RepositoryException;
+import org.apache.wicket.Component;
import org.apache.wicket.model.IModel;
import org.apache.wicket.request.resource.ResourceReference;
import org.hippoecm.frontend.l10n.ResourceBundleModel;
@@ -144,4 +145,10 @@
return null;
}
+ @Override
+ public Component getIcon(String id, IconSize size) {
+ return null;
+ }
+
+
}
diff --git a/perspectives/src/main/java/org/hippoecm/frontend/plugins/cms/browse/section/SearchingSectionPlugin.java b/perspectives/src/main/java/org/hippoecm/frontend/plugins/cms/browse/section/SearchingSectionPlugin.java
index 450712b..9d09210 100644
--- a/perspectives/src/main/java/org/hippoecm/frontend/plugins/cms/browse/section/SearchingSectionPlugin.java
+++ b/perspectives/src/main/java/org/hippoecm/frontend/plugins/cms/browse/section/SearchingSectionPlugin.java
@@ -56,6 +56,7 @@
import org.hippoecm.frontend.service.IconSize;
import org.hippoecm.frontend.service.render.RenderPlugin;
import org.hippoecm.frontend.skin.Icon;
+import org.hippoecm.frontend.skin.IconProvider;
import org.hippoecm.repository.api.HippoNodeType;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -337,6 +338,11 @@
public ResourceReference getIcon(IconSize type) {
return null;
}
+
+ @Override
+ public Component getIcon(String id, IconSize size) {
+ return null;
+ }
private boolean hasSearchResult() {
return collection.getType() == DocumentCollectionType.SEARCHRESULT;
Next steps?
And what happend with the retrolambda compilation of HippoCms?
Even some mistake … we have to solve static method …
[ERROR] hippo-cms/workflow/frontend/src/main/java/org/hippoecm/frontend/plugins/reviewedactions/list/ReviewedActionsListColumnProviderPlugin.java:[72,38] error: cannot find symbol
[ERROR] symbol: method of(Calendar)
[ERROR] location: interface DateTimePrinter
[ERROR] hippo-cms/workflow/frontend/src/main/java/org/hippoecm/frontend/plugins/reviewedactions/list/ReviewedActionsListColumnProviderPlugin.java:[79,38] error: cannot find symbol
[ERROR] symbol: method of(Calendar)
[ERROR] location: interface DateTimePrinter
Static methods on interfaces are backported by moving the static methods to a companion class (interface name + "$"), and by changing all methods calls to call the new method location.[1]
In this case, the temporary solution is to change the import in the classes of the second module, the companion class.
diff --git a/workflow/frontend/src/main/java/org/hippoecm/frontend/plugins/reviewedactions/RequestsView.java b/workflow/frontend/src/main/java/org/hippoecm/frontend/plugins/reviewedactions/RequestsView.java
index 5a97066..ab938b7 100644
--- a/workflow/frontend/src/main/java/org/hippoecm/frontend/plugins/reviewedactions/RequestsView.java
+++ b/workflow/frontend/src/main/java/org/hippoecm/frontend/plugins/reviewedactions/RequestsView.java
@@ -41,7 +41,7 @@
import org.hippoecm.frontend.plugin.IPluginContext;
import org.hippoecm.frontend.plugins.reviewedactions.model.Request;
import org.hippoecm.frontend.plugins.reviewedactions.model.RequestModel;
-import org.hippoecm.frontend.plugins.standards.datetime.DateTimePrinter;
+import org.hippoecm.frontend.plugins.standards.datetime.DateTimePrinter$;
import org.hippoecm.frontend.plugins.standards.icon.HippoIcon;
import org.hippoecm.frontend.session.UserSession;
import org.hippoecm.frontend.skin.Icon;
@@ -110,7 +110,7 @@
String state = request.getState();
final String parameter = schedule != null ?
- DateTimePrinter.of(schedule).appendDST().print(FormatStyle.FULL) : "??";
+ DateTimePrinter$.of(schedule).appendDST().print(FormatStyle.FULL) : "??";
return new StringResourceModel("state-" + state, this, null, "unknown", parameter);
}
Final notes
If you’ve used in your project with JDK 8 are streaming APIs, you can use this.
Here is a brief history.
Twitter
Google+
Facebook
Reddit
LinkedIn
StumbleUpon
Email