question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Add method signatures for JDK >= 11

See original GitHub issue

Hello, the following methods have been added in or after JDK 11. Would it make sense to consider them?

For the following methods added in JDK 17 I am not sure if they should be considered. For the Standard In and Out and Error steams it might make sense to use the native / default encoding; though if the other process explicitly specifies an encoding, that should of course be used.

I found these methods using the newly added “New” tab of the Javadoc: https://docs.oracle.com/en/java/javase/17/docs/api/new-list.html (see JDK-8269400). Maybe that can be useful for you in the future as well. However, this information is based on the @since tag. So if the JDK authors forget it you will miss APIs. It apparently also only considers direct usage of @since. So if a class is annotated with @since, but its methods are not, then only the class is listed as new.

In case you were not aware of it already, there are also https://github.com/AdoptOpenJDK/jdk-api-diff and https://github.com/marchof/java-almanac/; but for both the output is rather verbose given that mainly newly added methods and contructors are relevant for this project.

Issue Analytics

  • State:closed
  • Created 2 years ago
  • Comments:8 (5 by maintainers)

github_iconTop GitHub Comments

1reaction
uschindlercommented, Mar 24, 2022

I am working on the process to releasea new version with JDK 18 support, so I will look into this today. Adding the signatures should be easy.

1reaction
Marcono1234commented, Nov 6, 2021

Maybe the following < JDK 11 methods should be added as well (probably not worth it to create a separate GitHub issue):

Note that the signatures above don’t exactly match the ones used by this project; they have to be adjusted.

In case you are interested, I have written a small CodeQL query which can be used to find callables using default Charset or Locale. You can use it on https://lgtm.com to run against public GitHub projects, for example Apache Commons IO. It might however produce some false positives and have some false negatives.

CodeQL query
import java

class CharsetOrLocaleParam extends Parameter {
    CharsetOrLocaleParam() {
        getType().hasName(["Charset", "Locale"])
        or
        // Or is charset name as String
        getType() instanceof TypeString
        and exists(getName().regexpFind("(?i)(charset|encoding)", _, _))
    }
}

predicate usesDefault(Callable c) {
    // Either Javadoc mentions default Charset or Locale
    exists(string javadoc |
        // Join Javadoc lines using " "
        javadoc = concat(JavadocText javadocText |
            javadocText.getJavadoc().getCommentedElement() = c
        |
            javadocText.getText(), " " order by javadocText.getLocation().getStartLine() asc
        )
        and exists(javadoc.regexpFind("(?i)(default|platform)\\s+(locale|charset|encoding)", _, _))
        and not c.getAParameter() instanceof CharsetOrLocaleParam
    )
    // Or overload with Charset or Locale parameter exists
    or exists(Callable overload |
        overload.getDeclaringType() = c.getDeclaringType()
        and overload.getName() = c.getName()
        and overload != c
        and (
            // Either has no parameters
            c.hasNoParameters()
            and overload.getAParameter() instanceof CharsetOrLocaleParam
            or
            // Or has same parameters except for Charset / Locale parameter
            exists (int specificIndex |
                overload.getNumberOfParameters() = c.getNumberOfParameters() + 1
                and overload.getParameter(specificIndex) instanceof CharsetOrLocaleParam
                and forall(int smallerIndex |
                    smallerIndex = [0..specificIndex - 1]
                |
                    c.getParameterType(smallerIndex) = overload.getParameterType(smallerIndex)
                )
                and forall(int largerIndex |
                    largerIndex = [specificIndex + 1..overload.getNumberOfParameters() - 1]
                |
                    c.getParameterType(largerIndex - 1) = overload.getParameterType(largerIndex)
                )
            )
            // Ignore false positives from detection above
            and not c.getAParameter() instanceof CharsetOrLocaleParam
        )
        // Ignore if documentation says default is UTF-8 (e.g. java.nio.file.Files methods)
        and not exists(JavadocText javadocText |
            javadocText.getJavadoc().getCommentedElement() = c
            and exists(javadocText.getText().regexpFind("(?i)UTF(\\-| )8", _, _))
        )
    )
}

// Build signature in the format specified by https://github.com/policeman-tools/forbidden-apis/wiki/SignaturesSyntax
string getQualifiedTypeName(Type t) {
    if t instanceof Array then result = getQualifiedTypeName(t.(Array).getElementType()) + concat(int i | i = [1..t.(Array).getDimension()] | "[]")
    else if t instanceof RefType then result = t.(RefType).getSourceDeclaration().getQualifiedName()
    else result = t.getName()
}

string getParameters(Callable c) {
    result = "(" + concat(Parameter p |
        p = c.getAParameter()
    |
        getQualifiedTypeName(p.getType()), "," order by p.getPosition() asc
    ) + ")"
}

string getQualifiedName(Callable c) {
    exists(string callableName |
        result = c.getDeclaringType().getQualifiedName() + "#" + callableName + getParameters(c)
    |
        c instanceof Method and callableName = c.getName()
        or c instanceof Constructor and callableName = "<init>"
    )
}

from Callable c, string qualifiedName
where
    c.fromSource()
    // Only consider publicly visible callables
    and (c.isProtected() or c.isPublic())
    and forall(RefType t |
        t = c.getDeclaringType().getEnclosingType*()
    |
        t.isProtected() or t.isPublic()
    )
    and not c.getDeclaringType() instanceof TestClass
    and usesDefault(c)
    and qualifiedName = getQualifiedName(c)
// IMPORTANT: qualifiedName might not match exactly the format used by https://github.com/policeman-tools/forbidden-apis
select qualifiedName, c order by qualifiedName
Read more comments on GitHub >

github_iconTop Results From Across the Web

Method (Java SE 11 & JDK 11 ) - Oracle Help Center
Method Summary ; Returns an array of Type objects that represent the formal parameter types, in declaration order, of the executable represented by...
Read more >
Method Signature in Java - Scaler Topics
Method Signature in java is defined as the structure of a method that is designed by the programmer. Method Signature is the combination...
Read more >
Why doesn't Java support adding `throws` to the method ...
The throws clause is ignored by the JVM verifier, so there is no need for a bridge or other synthetic method. The compiler...
Read more >
The Basics of Java Generics - Baeldung
As mentioned, the method can deal with more than one generic type. Where this is the case, we must add all generic types...
Read more >
Java Generics Example Tutorial - Generic Method, Class ...
So if we try to add any other type of object in the list, the program ... Notice the isEqual method signature showing...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found