質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
87.20%
Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

解決済

Abstractクラスの実装クラスが複数存在する状態でアプリケーションを実行するとAbstractMethodErrorが起きる

sushikora
sushikora

総合スコア0

Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

1回答

0評価

0クリップ

22閲覧

投稿2019/04/02 06:50

Javaでアプリケーション開発を行っていますが、実行時にAbstractMethodErrorが起きてしまい困っています。

Java

Exception in thread "main" java.lang.AbstractMethodError: javax.ws.rs.core.UriBuilder.uri(Ljava/lang/String;)Ljavax/ws/rs/core/UriBuilder; at javax.ws.rs.core.UriBuilder.fromUri(UriBuilder.java:119) at org.glassfish.jersey.client.JerseyWebTarget.<init>(JerseyWebTarget.java:71) at org.glassfish.jersey.client.JerseyClient.target(JerseyClient.java:211) at org.glassfish.jersey.client.JerseyClient.target(JerseyClient.java:72)

以下、実装方法について順を追って説明します。
コードについては、必要箇所のみ抜粋しておりますのでご留意ください。

以下が、基底となるAbstractクラスです。
参照ライブラリであり、javax.ws.rs.coreパッケージに位置します。

Java

package javax.ws.rs.core; import java.lang.reflect.Method; import java.net.URI; import java.util.Map; import javax.ws.rs.core.Link; import javax.ws.rs.core.UriBuilderException; import javax.ws.rs.ext.RuntimeDelegate; public abstract class UriBuilder { protected static UriBuilder newInstance() { return RuntimeDelegate.getInstance().createUriBuilder(); } public static UriBuilder fromUri(String uriTemplate) { return newInstance().uri(uriTemplate); } /** 呼び出したいAbstractメソッド */ public abstract UriBuilder uri(String arg0);

次に、実装クラスです。
参照ライブラリであり、org.glassfish.jersey.uri.internalパッケージに位置します。

Java

package org.glassfish.jersey.uri.internal; import java.lang.reflect.AnnotatedElement; import java.lang.reflect.Method; import java.net.URI; import java.net.URISyntaxException; import java.security.AccessController; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Map.Entry; import javax.ws.rs.Path; import javax.ws.rs.core.MultivaluedMap; import javax.ws.rs.core.UriBuilder; import javax.ws.rs.core.UriBuilderException; import jersey.repackaged.com.google.common.collect.Maps; import jersey.repackaged.com.google.common.net.InetAddresses; import org.glassfish.jersey.internal.LocalizationMessages; import org.glassfish.jersey.internal.util.ReflectionHelper; import org.glassfish.jersey.internal.util.collection.MultivaluedStringMap; import org.glassfish.jersey.uri.UriComponent; import org.glassfish.jersey.uri.UriTemplate; import org.glassfish.jersey.uri.UriComponent.Type; import org.glassfish.jersey.uri.internal.UriParser; public class JerseyUriBuilder extends UriBuilder { private String scheme; private String ssp; private String authority; private String userInfo; private String host; private String port; private final StringBuilder path; private MultivaluedMap<String, String> matrixParams; private final StringBuilder query; private MultivaluedMap<String, String> queryParams; private String fragment; /** UriBuilder.uri(String str)の実装メソッド */ public JerseyUriBuilder uri(String uriTemplate) { if(uriTemplate == null) { throw new IllegalArgumentException(LocalizationMessages.PARAM_NULL("uriTemplate")); } else { UriParser parser = new UriParser(uriTemplate); parser.parse(); String parsedScheme = parser.getScheme(); if(parsedScheme != null) { this.scheme(parsedScheme); } else if(this.ssp != null) { this.ssp = null; parser = new UriParser(this.scheme + ":" + uriTemplate); parser.parse(); } this.schemeSpecificPart(parser); String parserFragment = parser.getFragment(); if(parserFragment != null) { this.fragment(parserFragment); } return this; } } }

UriBuilderクラスを継承しているクラスが上記の1つだけだと特に問題なく動作します。

しかし、以下クラス群が存在している状態だとエラーになります。
以下は全て参照ライブラリであり、org.restlet.ext.jaxrsパッケージに位置します。

Java

package org.restlet.ext.jaxrs; import java.io.IOException; import java.lang.reflect.Method; import java.net.URI; import java.net.URISyntaxException; import java.util.ArrayList; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; import javax.ws.rs.core.UriBuilder; import javax.ws.rs.core.UriBuilderException; import org.restlet.ext.jaxrs.internal.exceptions.IllegalPathException; import org.restlet.ext.jaxrs.internal.exceptions.IllegalPathOnClassException; import org.restlet.ext.jaxrs.internal.exceptions.IllegalPathOnMethodException; import org.restlet.ext.jaxrs.internal.exceptions.MissingAnnotationException; import org.restlet.ext.jaxrs.internal.todo.NotYetImplementedException; import org.restlet.ext.jaxrs.internal.util.EncodeOrCheck; import org.restlet.ext.jaxrs.internal.util.Util; import org.restlet.routing.Template; import org.restlet.util.Resolver; /** UriBuilderの実装クラスだが、uri(String str)は実装されていない */ public abstract class AbstractUriBuilder extends UriBuilder { public UriBuilder uri(URI uri) throws IllegalArgumentException { if(uri == null) { throw new IllegalArgumentException("The URI must not be null"); } else { if(uri.getScheme() != null) { this.scheme = uri.getScheme(); } if(uri.getHost() != null) { this.host = uri.getHost(); } this.port(uri.getPort()); if(uri.getRawUserInfo() != null) { this.userInfo = uri.getRawUserInfo(); } if(uri.getRawPath() != null) { this.replacePath(uri.getRawPath()); } if(uri.getRawQuery() != null) { this.query = uri.getRawQuery(); } if(uri.getRawFragment() != null) { this.fragment = uri.getRawFragment(); } return this; } }

上記クラスのサブクラスです。

Java

package org.restlet.ext.jaxrs; import java.lang.reflect.Method; import java.net.URI; import java.util.Map; import java.util.StringTokenizer; import javax.ws.rs.core.UriBuilderException; import org.restlet.Application; import org.restlet.data.Language; import org.restlet.data.MediaType; import org.restlet.data.Metadata; import org.restlet.ext.jaxrs.AbstractUriBuilder; import org.restlet.ext.jaxrs.internal.util.Util; import org.restlet.service.MetadataService; /* AbstractUriBuilderのサブクラス、こちらにもuri(String string)は実装されていない */ public class ExtendedUriBuilder extends AbstractUriBuilder { public ExtendedUriBuilder uri(URI uri) throws IllegalArgumentException { super.uri(uri); return this; } }

これらのライブラリがビルドパスに含まれていると、AbstractMethodErrorとなります。
恐らく、引数がString型のuriメソッドを呼び出したいのに、その実装メソッドが存在しないExtendedUriBuilderクラスをロードしてしまうことで発生しているような気がします。

解決策をいろいろと模索した上で発生した疑問点としては以下2つです。

①ExtendedUriBuilderクラスの含まれるライブラリのビルドパスの優先順位を下げたにも関わらず、AbstractMethodErrorとなるのはなぜでしょうか?末端のサブクラス(ExtendedUriBuilder)が最優先でロードされてしまっているのでしょうか?

②ExtendedUriBuilderクラスをオーバライド(※2)し、Stringを引数に持つuriメソッドを実装したにも
関わらず、そのメソッドが呼出すらされずにAbstractMethodErrorとなるのはなぜでしょうか?末端のサブクラスが最優先でロードされるのであるとすれば、こちらが呼ばれないのは不自然な気がします。

(※2)

package

import javax.ws.rs.core.UriBuilder; import org.glassfish.jersey.uri.internal.JerseyUriBuilder; import org.restlet.ext.jaxrs.ExtendedUriBuilder; public class UriBuilder2 extends ExtendedUriBuilder{ @Override public UriBuilder uri(String uri) throws IllegalArgumentException { JerseyUriBuilder jub = new JerseyUriBuilder(); jub.uri(uri); return this; } } コード

回答宜しくお願い致します。

良い質問の評価を上げる

以下のような質問は評価を上げましょう

  • 質問内容が明確
  • 自分も答えを知りたい
  • 質問者以外のユーザにも役立つ

評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

気になる質問をクリップする

クリップした質問は、後からいつでもマイページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

  • プログラミングに関係のない質問
  • やってほしいことだけを記載した丸投げの質問
  • 問題・課題が含まれていない質問
  • 意図的に内容が抹消された質問
  • 過去に投稿した質問と同じ内容の質問
  • 広告と受け取られるような投稿

評価を下げると、トップページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

まだ回答がついていません

会員登録して回答してみよう

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
87.20%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問

同じタグがついた質問を見る

Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。