Using Lambdaj to Navigate Through Dom4j Elements - junit4

For anyone familiar with lambdaj (not I) you will have seen this stacktrace, or some variation, before:
ch.lambdaj.function.argument.ArgumentConversionException: Unable to
convert the placeholder org.dom4j.tree.AbstractAttribute in a valid
argument at
ch.lambdaj.function.argument.ArgumentsFactory.actualArgument(ArgumentsFactory.java:92)
at
ch.lambdaj.function.matcher.HasArgumentWithValue.havingValue(HasArgumentWithValue.java:70)
at ch.lambdaj.Lambda.having(Lambda.java:1204)
My understadning is that this happens through a limitation of lambdaj with final classes.
I get the above when testing the following code:
import static ch.lambdaj.Lambda.having;
import static ch.lambdaj.Lambda.selectFirst;
import static org.hamcrest.CoreMatchers.equalTo;
import java.util.List;
import org.dom4j.tree.AbstractAttribute;
public class DocumentUtils {
public static String getAttributeValueFromListByName(
List<AbstractAttribute> list, String name) {
AbstractAttribute requiredAttribute = selectFirst(list,
having((AbstractAttribute.class).getName(), equalTo(name)));
String value = requiredAttribute.getValue();
return value;
}
}
I had been using dom4j's Attribute interface, getting the same problem, then thought maybe lambdaj doesn't like interfaces.. so I switched to the AbstractAttribute abstract class.
Is there an issue with lambdaj and abstract classes? Or is my method just pants? Any ideas how to solve this?
FYI: I'm using lambdaj 2.4 and dom4j 1.6
Thanks a lot in advance.

If you're using lambdaj 2.4 you're lucky because this issue has been fixed in that release. The problem and its solution is described in the first point of the release notes of lambdaj 2.4.
In particular lambdaj uses an internal heuristic to create Argument's placeholder, but it doesn't work in some cases, so you can override it as explained there.

Issue 92 has been raised with lambdaj, as requested by Mario Fusco (LambdaJ Developer)

Related

Eclipse fails to auto-suggest Jackson class

What is causing Eclipse to NOT recognize and consequently not offer any suggestion on an import of JsonParser.Feature as shown in the picture below:
Manually adding the static import of com.fasterxml.jackson.core.JsonParser.Feature.ALLOW_SINGLE_QUOTES (commented in the picture above), however, works fine.
Would it be the case that something is eclipsing the file on the classpath, and if so - what is Eclipse's strategy on resolving those conflicts? Or is it something else?
Thank you in advance.
You cannot use JsonParser class to access Feature since it is not a static member of the class. Instead you can directly use the Feature class :
mapper.configure(Feature.ALLOW_SINGLE_QUOTES, true);
I can suggest 2 workarounds:
Use AutoComplete (Ctrl + Space) to suggest classes:
Add . to class Name (JsonParser.) and then remove it (JsonParser) it will suggest all JsonParser classes:

AEM Osgi Sling Model #PostConstruct never called

I am having an issue with the javax.annotation.PostConstruct annotation in my Sling model.
My html file that uses my model:
<div data-sly-use="com.company.platform.component.general.textblockvalidator.TextBlockValidatorModel" data-sly-unwrap />
Model:
import org.apache.sling.api.resource.ResourceResolver;
import org.apache.sling.models.annotations.Model;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.annotation.PostConstruct;
import javax.inject.Inject;
#Model(adaptables = org.apache.sling.api.resource.Resource.class)
public class TextBlockValidatorModel {
#PostConstruct
private void init() {
System.out.println();
}
public String getValidate(){
return "This works";
}
}
I can call the getter from my sightly file but I never seem to enter my #PostConstruct init() method.
IntelliJ does give me a warning on the annotation but I am not sure what I am doing wrong:
Sling-model-packages:
<Sling-Model-Packages>
...
com.asadventure.platform.component
...
</Sling-Model-Packages>
Any ideas? Thanks in advance!
First, check your Sling Model has been registered correctly by looking for your class in this web page:
http://localhost:4502/system/console/status-adapters
If it isn't listed there, you most likely have not specified the <Sling-Model-Packages> property of the maven-bundle-plugin.
I would also try changing the access modifier for the init method to protected or public.
UPDATE:
I've created a sample project for AEM 6.1 demonstrating the use of the #PostConstruct annotation.
The Sling Model class:
#Model(adaptables = Resource.class)
public class SampleModel {
private boolean postContructCalled = false;
#PostConstruct
public void init() {
this.postContructCalled = true;
}
public boolean isPostContructCalled() {
return this.postContructCalled;
}
}
And a simple HTL component:
<sly data-sly-use.model="com.github.mickleroy.models.SampleModel">
<p>#PostConstruct was called: ${model.postContructCalled}</p>
</sly>
Please take note of the use of the data-sly-use directive - you need to provide a model name.
Also, as I mentioned in the comments, you should not be adding javax.annotation-api as a dependency as it is part of the JDK.
Full source available here: https://github.com/mickleroy/sling-models-sample
For anyone still looking for an answer to this that the above did not resolve, the issue for me was that I did not include the javax.annotation-api dependency:
<dependency>
<groupId>javax.annotation</groupId>
<artifactId>javax.annotation-api</artifactId>
<version>1.3.2</version>
<scope>provided</scope>
</dependency>
Once I added this in the parent pom, and its inclusion in the core pom, #PostConstruct worked just fine.
Update:
The reason I had to do this was because of my inclusion of jersey-client, which requires its own version of javax.annotation-api. Since my first rendition of this answer, I have found I needed to separate jersey-client and its dependencies into a separate bundle project. This allows both Jersey and #PostConstruct to work at the same time.
Just adding the dependency as the answer shows above caused issues with dependency clashes between Jersey's version of javax.annotation-api and AEM's version (Felix's version) of javax.annotation-api.
My guess is that your class is being initialized by the Java Use provider instead of adapting the current resource or request.
In sightly, when you use data-sly-use, it tries several things to obtain an object (I cant recall the order):
get an Osgi service with that name
use the AEM Java USE Api
Adapt the current request / resource into your model class (your desired case)
simply treat the class as a Java Pojo and instantiate it (post construct is not called, injection wont be done).
I've seen several cases where the injection or postconstruct methods of the sling models fails and sightly defaults to the java Use provider. If this happens what you describe happens. You have an object of the right class, but no injection happened and no post construct was called.
My recommendation is to careful check the logs, you should see an error if this is the case. Also, you can install the Scripting HTL Sling Models Use Provider which will propagate any error creating the sling model, making the problem obvious.

Fatal Error: 'Declaration of Zend_Pdf_FileParserDatasource_File::__contruct() must be compatible

Does anyone got this error?
Fatal Error: 'Declaration of Zend_Pdf_FileParserDatasource_File::__contruct() must be compatible with Zend_Pdf_FileParderDatasource::__construct() in /var/www/abc/app/vendors/Zend/Pdf/FileParserDataSource/File.php
I've googled a lot but still not find out the way to fix this bug.
you can change the constructor function of lib/Zend/Pdf/FileParserDataSource.php
abstract public function __construct();
to
abstract public function __construct($filePath);
and it works like a charm.
Have you tried commenting out __construct and __destruct abstract methods in Zend/Pdf/FileParserDataSource.php
// abstract public function __construct();
// abstract public function __destruct();
It worked for me.
This error has something to do with inheritance in latest versions of PHP.
At the moment I write this answer, all you need to do is upgrade your Zend_PDF library. The bug has been fixed and ff you here because you are using Magento and has faced this issue, just do the upgrade and it should be fine. ;-)
This bug appears to be happening for me on Magento installs on PHP 5.4 and above. I corrected it by using Afroz Alam's answer of changing
abstract public function __construct();
to
abstract public function __construct($filePath);
in the file lib/Zend/Pdf/FileParserDataSource.php
Change: abstract public function __construct(); to abstract public function __construct($filePath);
Location:lib/Zend/Pdf/FileParserDataSource.php
This works for me.

Conditional class import/ load

In a Groovy script is it possible to do a conditional import statement?
if (test){
import this.package.class
} else {
import that.package.class
}
The background to this is wanting to use something on MacOS 10.5 which only has JDK1.5 so one specific class is unavailable, but I have found someone who has written a back-port for it.
There is no way to conditionally import a class, but you can achieve something similar by attempting to load the class and then load another class if that one is not found.
Here's just an example:
def someClass
try {
someClass = "org.apache.webdavlib.WebdavFile" as Class
} catch (Exception ex) {
someClass = "java.io.File" as Class
}
def someInstance = someClass.newInstance("~/project/temp.log")
assert "java.io.File" == someInstance.getClass().getName()
Jochen "blackdrag" Theodorou proposed the following on the groovy user list a while ago:
wsh = this.class.classLoader.loadClass("org.codehaus.groovy.scriptom.ActiveXObject").newInstance("WScript.Shell")
Then you do not need to use the import statement.
Here is the thread on the mailing list
No, conditional imports are not supported... Best I can think of atm would be to use reflection as you would need to in java...
An ast transform could also be used here to tag the class and wrap the code that uses the missing class with the required reflection code
I guess a class loader could do the trick, but will be complicated.
Have you considered to use a shadow class and jsut deploy different jars?
Something like
//jdk 1.5
somethingelse extends this {
}
.
//jdk 1.6
somtheingelse extends that {
}
=> compile both to two different jar files, which you deploy on one system but not the other...
not perfect, but could work
...wait: if your libraries just differ in the package name, then you don't need a shadow class. Can't you move the one or the other in the same package?

How to refer to protected inner class in Scala when inheriting from Java (with byte code only)

I am writing a Scala class to inherit from a Java class, and I must override a method that takes a protected Java inner class as a parameter. The Java dependency comes as a jar without source code.
I have the exact same setup as found in https://issues.scala-lang.org/browse/SI-3120 except that I do not have the Java source code available, so scalac only knows about the Java dependency by looking at the byte code (in jar or class files).
This is basically what I'm trying to do:
// javapkg/JavaSuperClass.java
package javapkg;
public class JavaSuperClass {
protected class JavaInnerClass {
}
public void method(JavaInnerClass javaInnerclass) {
System.out.println("hello");
}
}
// scalapkg/ScalaSubClass.scala
package scalapkg
import javapkg.JavaSuperClass
class ScalaSubClass extends JavaSuperClass {
override def method(javaInnerClass: JavaSuperClass#JavaInnerClass) {
println("world")
}
}
I have Java Sun JDK Hotspot 1.6.0_24 and Scala 2.9.0.1 on Linux. This is what happens:
$ cd javapkg
$ javac JavaSuperClass.java
$ cd ../scalapkg
$ scalac -cp .. ScalaSubClass.scala
ScalaSubClass.scala:6: error: class JavaInnerClass in class JavaSuperClass cannot be accessed in javapkg.JavaSuperClass
Access to protected class JavaInnerClass not permitted because
prefix type javapkg.JavaSuperClass does not conform to
class ScalaSubClass in package scalapkg where the access take place
override def method(javaInnerclass: JavaSuperClass#JavaInnerClass) {
^
one error found
Note, if I change JavaSuperClass#JavaInnerClass to simply JavaInnerClass, I get this:
ScalaSubClass.scala:6: error: method method overrides nothing
override def method(javaInnerClass: JavaInnerClass) {
^
one error found
Note: I know this sounds very similar to the common "protected static inner class" Java-compatibility issue in Scala, but I believe this is unrelated because there are no statics anywhere in my example.
I feel like something is wrong, because when I put the same code into a mixed java/scala project in Eclipse, it seemed to compile fine (with the latter JavaInnerClass syntax); it's only when I compile the Scala code with only the Java byte code (and no Java source code) that I cannot get it to work. Am I just completely missing the correct syntax to refer to a Java inner class, is this a known defect, or should I file a compiler bug? I couldn't find anything about this exact use case in my searching.
This is an excellent article that discuss the topic.
EDIT-1
My bad, I answered to quickly. This actually may be a bug Mike, I'm trying to see if I can find a hack around. I'll let you know if I find one.
EDIT-2
I've tried different things but I can't find a way to make it work. Mike I'd suggest you to file a bug report.