Sebastian Hoß
unread,Dec 14, 2009, 11:24:50 AM12/14/09Sign in to reply to author
Sign in to forward
You do not have permission to delete messages in this group
Either email addresses are anonymous for this group or you need the view member email addresses permission to view the original message
to Google Collections Library - users list
Hey there,
I'm currently writing a small library and while doing that I deal with
collections quite often. Since I don't want to allow adding any
elements to those collections I enforced certain constraints like in
the following via delegated addXXX and addAllXXX methods:
public boolean addElement(final Type element) {
if (!this.collection.containts(element)) {
if (element != null) {
return this.collection.add(element);
}
throw new NullPointerException("May not add 'null'");
}
throw new IllegalArgumentException("May not add duplicate
elements");
}
Or even more type-related constraints like certain values must be
above a given threshold or whatever. But instead of writing the same
constraints over and over again I thought about a CollectionJoiner
which works similar to the String Joiner class from the google
collections library.
In my current code it looks like this:
join(this.collection).with(element);
With that one can join a given collection with another element/
collection while also checking for the given constraints. In my case
I'm enforcing certain constraints to all collections and elements but
I wanted to add the ability to add extra constraints where needed. For
that I defined a method like the following:
public CollectionJoiner<T> enforce(final Predicate<T>
anotherPredicate) {
this.predicate = Predicates.and(this.predicate,
anotherPredicate);
return this;
}
With that one could write something like this:
join(this.collection).enforce(Predicates.notNull()).with(element);
As you can see I'm now using the Predicate<T> class for my constraints
and I want to "add" the given predicate the already given predicate.
The problem here is that I get a compilation failure when running this
through maven. The debug output is as follows:
[INFO] [compiler:compile {execution: default-compile}]
[DEBUG] Using compiler 'javac'.
[DEBUG] Source directories: [/home/seb/Projekte/Denove/util/src/main/
java]
[DEBUG] Classpath: [/home/seb/Projekte/Denove/util/target/classes
/home/seb/.m2/repository/com/google/collections/google-collections/
1.0-rc5/google-collections-1.0-rc5.jar]
[DEBUG] Output directory: /home/seb/Projekte/Denove/util/target/
classes
[DEBUG] Classpath:
[DEBUG] /home/seb/Projekte/Denove/util/target/classes
[DEBUG] /home/seb/.m2/repository/com/google/collections/google-
collections/1.0-rc5/google-collections-1.0-rc5.jar
[DEBUG] Source roots:
[DEBUG] /home/seb/Projekte/Denove/util/src/main/java
[INFO] Compiling 6 source files to /home/seb/Projekte/Denove/util/
target/classes
[INFO]
------------------------------------------------------------------------
[ERROR] BUILD FAILURE
[INFO]
------------------------------------------------------------------------
[INFO] Compilation failure
/home/seb/Projekte/Denove/util/src/main/java/org/denove/util/
collection/AbstractCollectionJoiner.java:[91,25] cannot find symbol
symbol : method and
(com.google.common.base.Predicate<T>,com.google.common.base.Predicate<T>)
location: class org.denove.util.collection.AbstractCollectionJoiner<T>
[INFO]
------------------------------------------------------------------------
[DEBUG] Trace
org.apache.maven.BuildFailureException: Compilation failure
/home/seb/Projekte/Denove/util/src/main/java/org/denove/util/
collection/AbstractCollectionJoiner.java:[91,25] cannot find symbol
symbol : method and
(com.google.common.base.Predicate<T>,com.google.common.base.Predicate<T>)
location: class org.denove.util.collection.AbstractCollectionJoiner<T>
at org.apache.maven.lifecycle.DefaultLifecycleExecutor.executeGoals
(DefaultLifecycleExecutor.java:715)
at
org.apache.maven.lifecycle.DefaultLifecycleExecutor.executeGoalWithLifecycle
(DefaultLifecycleExecutor.java:556)
at org.apache.maven.lifecycle.DefaultLifecycleExecutor.executeGoal
(DefaultLifecycleExecutor.java:535)
at
org.apache.maven.lifecycle.DefaultLifecycleExecutor.executeGoalAndHandleFailures
(DefaultLifecycleExecutor.java:387)
at
org.apache.maven.lifecycle.DefaultLifecycleExecutor.executeTaskSegments
(DefaultLifecycleExecutor.java:348)
at org.apache.maven.lifecycle.DefaultLifecycleExecutor.execute
(DefaultLifecycleExecutor.java:180)
at org.apache.maven.DefaultMaven.doExecute(DefaultMaven.java:328)
at org.apache.maven.DefaultMaven.execute(DefaultMaven.java:138)
at org.apache.maven.cli.MavenCli.main(MavenCli.java:362)
at org.apache.maven.cli.compat.CompatibleMain.main
(CompatibleMain.java:60)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke
(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke
(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at org.codehaus.classworlds.Launcher.launchEnhanced(Launcher.java:
315)
at org.codehaus.classworlds.Launcher.launch(Launcher.java:255)
at org.codehaus.classworlds.Launcher.mainWithExitCode(Launcher.java:
430)
at org.codehaus.classworlds.Launcher.main(Launcher.java:375)
Caused by: org.apache.maven.plugin.CompilationFailureException:
Compilation failure
/home/seb/Projekte/Denove/util/src/main/java/org/denove/util/
collection/AbstractCollectionJoiner.java:[91,25] cannot find symbol
symbol : method and
(com.google.common.base.Predicate<T>,com.google.common.base.Predicate<T>)
location: class org.denove.util.collection.AbstractCollectionJoiner<T>
at org.apache.maven.plugin.AbstractCompilerMojo.execute
(AbstractCompilerMojo.java:516)
at org.apache.maven.plugin.CompilerMojo.execute(CompilerMojo.java:
114)
at org.apache.maven.plugin.DefaultPluginManager.executeMojo
(DefaultPluginManager.java:490)
at org.apache.maven.lifecycle.DefaultLifecycleExecutor.executeGoals
(DefaultLifecycleExecutor.java:694)
... 17 more
The strange thing is that running the same code inside Eclipse during
JUnit tests works fine. The given predicates are picked up and applied
to each new element. And I can somehow work around this issue by
slightly changing the definition of the enforce()-method to the
following:
public CollectionJoiner<T> enforce(final Predicate<T>
anotherPredicate) {
// this.predicate = and(this.predicate,
anotherPredicate);
final Collection<Predicate<T>> predicates = new
ArrayList<Predicate<T>>();
predicates.add(this.predicate);
predicates.add(anotherPredicate);
this.predicate = Predicates.and(predicates);
return this;
}
This works both inside Eclipse and outside in Maven but looks ugly. Is
there something I could do to make my first example compile? I tried
changing the generic type of the Predicate to <? super T> but that
gives me the same compilation failure. Are there any examples on how
to use the Predicates.and() method or any source code I could take a
look at that you know of?
Greets,
Sebastian