class JavaId extends ConstructId {

  public URL getJarUrl() {
    // The JAR URL will be searched for the following construct (could be JavaClassId, JavaEnumId or
    // JavaInterfaceId)
    ConstructId cid = this;

    // For methods, constructors, etc., take its definition context
    if (cid instanceof JavaConstructorId
        || cid instanceof JavaMethodId
        || cid instanceof JavaClassInit) {
      cid = cid.getDefinitionContext();
    }
    // Not possible, we cannot get the JAR URL for a package
    else if (cid instanceof JavaPackageId) return null;

    // Use Javassist
    URL url = ClassPoolUpdater.getInstance().getJarResourcePath(cid);

    // Use Class.forName (if Javassist did not work)
    if (url == null || !url.toString().startsWith("jar:")) {
      try {
        url =
            Class.forName(this.getQualifiedName())
                .getResource('/' + this.getQualifiedName().replace('.', '/') + ".class");
      } catch (ClassNotFoundException e) {
        JavaId.log.error("Class [" + this.getQualifiedName() + "] not found: " + e.getMessage());
      } catch (NoClassDefFoundError ex) {
        JavaId.log.error("No class definition found for [" + this.getQualifiedName() + "]");
      } catch (UnsatisfiedLinkError e) {
        JavaId.log.error("UnsatisfiedLinkError for [" + this.getQualifiedName() + "]");
      }
    }

    // Transform "jar:file:/.../foo.jar!bar.class" into "file:/.../foo.jar"
    if (url != null && url.toString().startsWith("jar:")) {
      try {
        return JavaId.getJarUrl(url);
      } catch (MalformedURLException e) {
        JavaId.log.error("Cannot create URL from [" + url.toString() + "]: " + e.getMessage());
      }
    }

    // Return null
    return null;
  }

  protected  JavaId(Type _t);

}