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

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

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

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

Q&A

解決済

1回答

2570閲覧

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

sushikora

総合スコア17

Java

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

0グッド

0クリップ

投稿2019/04/02 06:50

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

Java

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

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

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

Java

1package javax.ws.rs.core; 2 3import java.lang.reflect.Method; 4import java.net.URI; 5import java.util.Map; 6import javax.ws.rs.core.Link; 7import javax.ws.rs.core.UriBuilderException; 8import javax.ws.rs.ext.RuntimeDelegate; 9 10public abstract class UriBuilder { 11 protected static UriBuilder newInstance() { 12 return RuntimeDelegate.getInstance().createUriBuilder(); 13 } 14 15 public static UriBuilder fromUri(String uriTemplate) { 16 return newInstance().uri(uriTemplate); 17 } 18 /** 呼び出したいAbstractメソッド */ 19 public abstract UriBuilder uri(String arg0); 20

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

Java

1package org.glassfish.jersey.uri.internal; 2 3import java.lang.reflect.AnnotatedElement; 4import java.lang.reflect.Method; 5import java.net.URI; 6import java.net.URISyntaxException; 7import java.security.AccessController; 8import java.util.HashMap; 9import java.util.Iterator; 10import java.util.List; 11import java.util.Map; 12import java.util.Map.Entry; 13import javax.ws.rs.Path; 14import javax.ws.rs.core.MultivaluedMap; 15import javax.ws.rs.core.UriBuilder; 16import javax.ws.rs.core.UriBuilderException; 17import jersey.repackaged.com.google.common.collect.Maps; 18import jersey.repackaged.com.google.common.net.InetAddresses; 19import org.glassfish.jersey.internal.LocalizationMessages; 20import org.glassfish.jersey.internal.util.ReflectionHelper; 21import org.glassfish.jersey.internal.util.collection.MultivaluedStringMap; 22import org.glassfish.jersey.uri.UriComponent; 23import org.glassfish.jersey.uri.UriTemplate; 24import org.glassfish.jersey.uri.UriComponent.Type; 25import org.glassfish.jersey.uri.internal.UriParser; 26 27public class JerseyUriBuilder extends UriBuilder { 28 private String scheme; 29 private String ssp; 30 private String authority; 31 private String userInfo; 32 private String host; 33 private String port; 34 private final StringBuilder path; 35 private MultivaluedMap<String, String> matrixParams; 36 private final StringBuilder query; 37 private MultivaluedMap<String, String> queryParams; 38 private String fragment; 39 40 /** UriBuilder.uri(String str)の実装メソッド */ 41 public JerseyUriBuilder uri(String uriTemplate) { 42 if(uriTemplate == null) { 43 throw new IllegalArgumentException(LocalizationMessages.PARAM_NULL("uriTemplate")); 44 45 } else { 46 UriParser parser = new UriParser(uriTemplate); 47 parser.parse(); 48 49 String parsedScheme = parser.getScheme(); 50 if(parsedScheme != null) { 51 this.scheme(parsedScheme); 52 } else if(this.ssp != null) { 53 54 this.ssp = null; 55 parser = new UriParser(this.scheme + ":" + uriTemplate); 56 parser.parse(); 57 } 58 59 this.schemeSpecificPart(parser); 60 61 String parserFragment = parser.getFragment(); 62 if(parserFragment != null) { 63 this.fragment(parserFragment); 64 } 65 return this; 66 } 67 } 68}

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

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

Java

1package org.restlet.ext.jaxrs; 2 3import java.io.IOException; 4import java.lang.reflect.Method; 5import java.net.URI; 6import java.net.URISyntaxException; 7import java.util.ArrayList; 8import java.util.HashMap; 9import java.util.Iterator; 10import java.util.List; 11import java.util.Map; 12import javax.ws.rs.core.UriBuilder; 13import javax.ws.rs.core.UriBuilderException; 14import org.restlet.ext.jaxrs.internal.exceptions.IllegalPathException; 15import org.restlet.ext.jaxrs.internal.exceptions.IllegalPathOnClassException; 16import org.restlet.ext.jaxrs.internal.exceptions.IllegalPathOnMethodException; 17import org.restlet.ext.jaxrs.internal.exceptions.MissingAnnotationException; 18import org.restlet.ext.jaxrs.internal.todo.NotYetImplementedException; 19import org.restlet.ext.jaxrs.internal.util.EncodeOrCheck; 20import org.restlet.ext.jaxrs.internal.util.Util; 21import org.restlet.routing.Template; 22import org.restlet.util.Resolver; 23 24/** UriBuilderの実装クラスだが、uri(String str)は実装されていない */ 25public abstract class AbstractUriBuilder extends UriBuilder { 26 27 public UriBuilder uri(URI uri) throws IllegalArgumentException { 28 if(uri == null) { 29 throw new IllegalArgumentException("The URI must not be null"); 30 } else { 31 if(uri.getScheme() != null) { 32 this.scheme = uri.getScheme(); 33 } 34 if(uri.getHost() != null) { 35 this.host = uri.getHost(); 36 } 37 this.port(uri.getPort()); 38 if(uri.getRawUserInfo() != null) { 39 this.userInfo = uri.getRawUserInfo(); 40 } 41 if(uri.getRawPath() != null) { 42 this.replacePath(uri.getRawPath()); 43 } 44 if(uri.getRawQuery() != null) { 45 this.query = uri.getRawQuery(); 46 } 47 if(uri.getRawFragment() != null) { 48 this.fragment = uri.getRawFragment(); 49 } 50 return this; 51 } 52 } 53

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

Java

1package org.restlet.ext.jaxrs; 2 3import java.lang.reflect.Method; 4import java.net.URI; 5import java.util.Map; 6import java.util.StringTokenizer; 7import javax.ws.rs.core.UriBuilderException; 8import org.restlet.Application; 9import org.restlet.data.Language; 10import org.restlet.data.MediaType; 11import org.restlet.data.Metadata; 12import org.restlet.ext.jaxrs.AbstractUriBuilder; 13import org.restlet.ext.jaxrs.internal.util.Util; 14import org.restlet.service.MetadataService; 15 16/* AbstractUriBuilderのサブクラス、こちらにもuri(String string)は実装されていない */ 17public class ExtendedUriBuilder extends AbstractUriBuilder { 18 19 public ExtendedUriBuilder uri(URI uri) throws IllegalArgumentException { 20 super.uri(uri); 21 return this; 22 } 23} 24

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

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

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

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

(※2)

package

1 2import javax.ws.rs.core.UriBuilder; 3 4import org.glassfish.jersey.uri.internal.JerseyUriBuilder; 5import org.restlet.ext.jaxrs.ExtendedUriBuilder; 6 7public class UriBuilder2 extends ExtendedUriBuilder{ 8 9 @Override 10 public UriBuilder uri(String uri) throws IllegalArgumentException { 11 JerseyUriBuilder jub = new JerseyUriBuilder(); 12 jub.uri(uri); 13 return this; 14 } 15} 16 17コード

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

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

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

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

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

自己解決

自己解決しました。

UriBuilderの実装クラスを生成するjavax.ws.rs.ext.RuntimeDelegateの実装クラスが、以下2つで重複していたためでした。

・org.restlet.ext.jaxrs.internal.spi.RuntumeDelegateImpl
・org.glassfish.jersey.internal.RuntimeDelegateImpl

実装クラスが重複する場合、何も指定をしない場合前者の実装クラスがロードされてしまうようでした。
前者のクラスはUriBuilderの実装クラスを直接呼び出しているため、オーバライドが効果を発揮していませんでした。
ですので、以下のファイルをsrc/META-INF/servicesに配備することで、後者の実装クラスを優先して
ロードするようにしました。

ファイル名:javax.ws.rs.ext.RuntimeDelegate

org.glassfish.jersey.server.internal.RuntimeDelegateImpl

結果、正常に動作しました。

投稿2019/04/03 04:51

sushikora

総合スコア17

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問