Just to double check: are you using 8u60 jdeps?  or jdk9 jdeps?

Mandy

On 09/01/2015 11:59 AM, Jeff Hain wrote:

Back from trying to figure out all the cases where
jdeps and my utility don't compute the same dependencies,
for classes of JDK8_60/rt.jar, and each time which
is right.


What I did is modify my code to make it behave like
jdeps for each encountered difference, and then
re-run the comparison to see what was left.


Below I list all the cases for usage of jdeps
with "-verbose:class -filter:none" options,
i.e. when computing all dependencies, API or not
(with "-apionly" option there were many more
differences, possibly due to assumptions about
what "API" means - we could exclude that for now).



1) Jdeps ignores dependencies caused by package-info
class files.
===> Maybe intended?

Ex.:
@javax.xml.bind.annotation.XmlSchema(namespace = "http://xmlns.oracle.com/webservices/jaxws-databinding";, elementFormDefault = javax.xml.bind.annotation.XmlNsForm.QUALIFIED)
package com.oracle.xmlns.internal.webservices.jaxws_databinding;
===> Doesn't see dependencies to
java.lang.Object
and
javax.xml.bind.annotation.XmlSchema



2) Jdeps ignores types of parameters of annotations
(as said in initial mail).

Ex. (in java.beans):
@Documented @Target(CONSTRUCTOR) @Retention(RUNTIME)
public @interface ConstructorProperties {
    String[] value();
}
===> Doesn't see dependencies to
java.lang.annotation.ElementType
and
java.lang.annotation.RetentionPolicy.

===> Could reproduce the behavior by ignoring/skipping
"element_value" items.



3) Jdeps doesn't parse class signatures containing generic types
properly, but it does fine for fields or methods signatures.

Ex. (in java.lang.management.PlatformComponent):
interface MXBeanFetcher<T extends PlatformManagedObject> {
    public List<T> getMXBeans();
}
===> Doesn't see dependency to
java.lang.management.PlatformManagedObject.

===> For example, dependency to Object is properly computed from signature
     "Ljava/lang/ThreadLocal<Ljava/lang/Object;>;"
     but not from
"<E:Ljava/lang/Object;>Ljava/lang/ThreadLocal<TE;>;".

===> Could reproduce the behavior by skipping all characters following ':'
     up to the '>' closing the scope.



4) Jdeps doesn't compute a dependency to java.lang.Deprecated when
@deprecated or @Deprecated is only in the Javadoc,
in which case there is no "Ljava/lang/Deprecated;" descriptor/signature
in the class file but still a "Deprecated" attribute.
===> Maybe intended?

Ex.: javax.xml.bind.Validator

===> Could reproduce the behavior by skipping "Deprecated" attributes,
and only having dependency to java.lang.Deprecated due to the descriptor/signature.



5) Jdeps ignores (some? all?) dependencies to
com.sun.istack.internal.NotNull
and
com.sun.istack.internal.Nullable

Ex. (in com.sun.istack.internal.Pool):
public interface Pool<T> {
    @NotNull T take();
    void recycle(@NotNull T t);
}
===> Doesn't see dependencies to
com.sun.istack.internal.NotNull

===> Could not find a way to reproduce this behavior, other than
having specific cases for these annotations.
I created a similar test class, with a similar annotation @MyNotNull,
and jdeps would detect it (???).



6) For java.util.stream.FindOps, jdeps properly doesn't compute
a dependency to java.util.stream.TerminalSink (which is only
used in nested classes), but for some reason there is a
"()Ljava/util/stream/TerminalSink;" descriptor in FindOps.class
(???) so my library considers there is the dependency...



Lastly a few remarks about -apionly:

jdeps help says it restricts the analysis to dependences
"from the signature of public and protected members of public
classes including field type, method parameter types,
returned type, checked exception types etc"

But:

1) It can actually compute dependencies from a protected,
   package-private or private class, for example if they
   have public fields.
   Maybe it should not be the case for (package-)private
   classes (or whenever there is a non-API class in the
   way to the top level class), because it would show
   transitive dependencies that could not be followed
   through the API.
   (Ex.:
    private class Priv {public Double getDouble(){...}}
    public class Pub {public Priv getPriv(){...}}
    ===> Through the API we could never go from Pub to Double
         but according to jdeps it would be possible.)

2) It does not consider public and protected nested classes
   as dependencies (even though they are in the API
   of the class).

3) Should annotations of APIs be considered APIs?
   (at least for some trivial cases they are)



-Jeff

------------------------------------------------------------------------
*De :* Jeff Hain <jeffh...@rocketmail.com>
*À :* Mandy Chung <mandy.ch...@oracle.com>; "jigsaw-dev@openjdk.java.net" <jigsaw-dev@openjdk.java.net>
*Envoyé le :* Jeudi 27 août 2015 23h24
*Objet :* Re: jdeps and annotations parameters


>It looks like a bug.  I have filed an issue to look into further:
> https://bugs.openjdk.java.net/browse/JDK-8134625
>Mandy

Ok.

I was starting to check my jdeps-like library
(an upgrade of sourceforge.net/projects/jcycles
to compute dependencies in various ways and with more info
(deps byte size, classes causing packages dependencies, etc.))
against jdeps on all rt.jar class files, and I'm starting to see a lot more
differences.

The idea was both:
- to check correctness of libraries against each other,
- and, where dependency-or-not would be conventional
  (such as, should a nested class always depend on its
surrounding class, or not, or on all of them up to top level one
(since they are all in InnerClasses attributes), etc.)
to use jdeps convention to keep things simple.

I will send you details (off list?) when I got them (with and without -apionly)
(test does Runtime.exec(jdeps) for each class, takes time :).

Then you could tell me what looks like a bug
and what looks like a convention.




-Jeff




Reply via email to