クイック統合
OSS Java SDK V1 を統合するには:
環境の準備
Java 7 以降をインストールします。java -version コマンドを実行して、Java のバージョンを確認できます。Java がインストールされていない場合、またはバージョンが Java 7 より前の場合は、Java をダウンロードしてください。
SDK のインストール
ご利用の環境に応じてインストール方法を選択してください。最新バージョンの OSS Java SDK V1 を使用することを推奨します。
以下の例では、OSS Java SDK V1 3.17.4 を使用します。
Maven 依存関係の追加 (推奨)
Maven プロジェクトで OSS Java SDK V1 を使用するには、対応する依存関係を pom.xml ファイルに追加します。
<dependency>
<groupId>com.aliyun.oss</groupId>
<artifactId>aliyun-sdk-oss</artifactId>
<version>3.18.4</version>
</dependency>
Java 9 以降を使用する場合は、以下の JAXB 関連の依存関係を追加してください。
<dependency>
<groupId>javax.xml.bind</groupId>
<artifactId>jaxb-api</artifactId>
<version>2.3.1</version>
</dependency>
<dependency>
<groupId>javax.activation</groupId>
<artifactId>activation</artifactId>
<version>1.1.1</version>
</dependency>
<!-- 2.3.3 以下 -->
<dependency>
<groupId>org.glassfish.jaxb</groupId>
<artifactId>jaxb-runtime</artifactId>
<version>2.3.3</version>
</dependency>
Eclipse プロジェクトへの JAR パッケージのインポート
-
OSS Java SDK V1 をダウンロードします。
-
パッケージを解凍します。
-
解凍したパッケージ内の aliyun-sdk-oss-3.17.4.jar ファイルと `lib` フォルダ内のすべてのファイルをプロジェクトにコピーします。
-
Eclipse で、プロジェクトを右クリックし、 を選択します。
-
コピーしたすべての JAR ファイルを選択し、ライブラリにインポートします。
IntelliJ IDEA プロジェクトへの JAR パッケージのインポート
-
OSS Java SDK V1 をダウンロードします。
-
パッケージを解凍します。
-
解凍したパッケージ内の aliyun-sdk-oss-3.17.4.jar ファイルと `lib` フォルダ内のすべての JAR ファイルをプロジェクトにコピーします。
-
IntelliJ IDEA で、プロジェクトを選択し、 を選択します。
-
コピーしたすべての JAR ファイルを選択し、外部ライブラリにインポートします。
アクセス認証情報の設定
Resource Access Management (RAM) ユーザーの AccessKey ペアを使用してアクセス認証情報を設定します。
-
RAM コンソールで、[永続的な AccessKey ペア] を持つ RAM ユーザーを作成します。AccessKey ペアを保存し、ユーザーに
AliyunOSSFullAccess権限を付与します。 -
RAM ユーザーの AccessKey ペアを使用して環境変数を設定します。
Linux
-
コマンドラインインターフェイスで次のコマンドを実行して、環境変数の設定を
~/.bashrcファイルに追加します。echo "export OSS_ACCESS_KEY_ID='YOUR_ACCESS_KEY_ID'" >> ~/.bashrc echo "export OSS_ACCESS_KEY_SECRET='YOUR_ACCESS_KEY_SECRET'" >> ~/.bashrc -
次のコマンドを実行して変更を適用します。
source ~/.bashrc -
次のコマンドを実行して、環境変数が設定されていることを確認します。
echo $OSS_ACCESS_KEY_ID echo $OSS_ACCESS_KEY_SECRET
macOS
-
ターミナルで次のコマンドを実行して、デフォルトのシェルタイプを表示します。
echo $SHELL -
デフォルトのシェルタイプに基づいて、次の操作を実行します。
Zsh
-
次のコマンドを実行して、環境変数の設定を
~/.zshrcファイルに追加します。echo "export OSS_ACCESS_KEY_ID='YOUR_ACCESS_KEY_ID'" >> ~/.zshrc echo "export OSS_ACCESS_KEY_SECRET='YOUR_ACCESS_KEY_SECRET'" >> ~/.zshrc -
次のコマンドを実行して変更を適用します。
source ~/.zshrc -
次のコマンドを実行して、環境変数が設定されていることを確認します。
echo $OSS_ACCESS_KEY_ID echo $OSS_ACCESS_KEY_SECRET
Bash
-
次のコマンドを実行して、環境変数の設定を
~/.bash_profileファイルに追加します。echo "export OSS_ACCESS_KEY_ID='YOUR_ACCESS_KEY_ID'" >> ~/.bash_profile echo "export OSS_ACCESS_KEY_SECRET='YOUR_ACCESS_KEY_SECRET'" >> ~/.bash_profile -
次のコマンドを実行して変更を適用します。
source ~/.bash_profile -
次のコマンドを実行して、環境変数が設定されていることを確認します。
echo $OSS_ACCESS_KEY_ID echo $OSS_ACCESS_KEY_SECRET
-
Windows
CMD
-
CMD で次のコマンドを実行します。
setx OSS_ACCESS_KEY_ID "YOUR_ACCESS_KEY_ID" setx OSS_ACCESS_KEY_SECRET "YOUR_ACCESS_KEY_SECRET" -
次のコマンドを実行して、環境変数が設定されていることを確認します。
echo %OSS_ACCESS_KEY_ID% echo %OSS_ACCESS_KEY_SECRET%
PowerShell
-
PowerShell で次のコマンドを実行します。
[Environment]::SetEnvironmentVariable("OSS_ACCESS_KEY_ID", "YOUR_ACCESS_KEY_ID", [EnvironmentVariableTarget]::User) [Environment]::SetEnvironmentVariable("OSS_ACCESS_KEY_SECRET", "YOUR_ACCESS_KEY_SECRET", [EnvironmentVariableTarget]::User) -
次のコマンドを実行して、環境変数が設定されていることを確認します。
[Environment]::GetEnvironmentVariable("OSS_ACCESS_KEY_ID", [EnvironmentVariableTarget]::User) [Environment]::GetEnvironmentVariable("OSS_ACCESS_KEY_SECRET", [EnvironmentVariableTarget]::User)
-
クライアントの初期化
以下のサンプルコードでは、中国 (杭州) リージョンのパブリックエンドポイントを使用してクライアントを初期化します。次に、アカウントが所有するすべてのバケットをリスト表示して、設定を検証します。リージョンとエンドポイントの完全なリストについては、「リージョンとエンドポイント」をご参照ください。
import com.aliyun.oss.*;
import com.aliyun.oss.common.auth.*;
import com.aliyun.oss.common.comm.SignVersion;
import com.aliyun.oss.model.Bucket;
import java.util.List;
/**
* OSS SDK クイック統合の例
* OSS クライアントを初期化し、すべてのバケットをリスト表示する方法を示します
*/
public class Test {
public static void main(String[] args) {
// 環境変数からアクセス認証情報を取得
String accessKeyId = System.getenv("OSS_ACCESS_KEY_ID");
String accessKeySecret = System.getenv("OSS_ACCESS_KEY_SECRET");
// OSS のリージョンとエンドポイントを設定
String region = "cn-hangzhou";
String endpoint = "oss-cn-hangzhou.aliyuncs.com";
// 認証情報プロバイダーを作成
DefaultCredentialProvider provider = new DefaultCredentialProvider(accessKeyId, accessKeySecret);
// クライアントパラメーターを設定
ClientBuilderConfiguration clientBuilderConfiguration = new ClientBuilderConfiguration();
// V4 署名アルゴリズムの使用を明示的に宣言
clientBuilderConfiguration.setSignatureVersion(SignVersion.V4);
// OSS クライアントを初期化
OSS ossClient = OSSClientBuilder.create()
.credentialsProvider(provider)
.clientConfiguration(clientBuilderConfiguration)
.region(region)
.endpoint(endpoint)
.build();
// 現在のユーザーのすべてのバケットをリスト表示
List<Bucket> buckets = ossClient.listBuckets();
System.out.println("Successfully connected to OSS. Buckets under the current account:");
if (buckets.isEmpty()) {
System.out.println("No buckets found under the current account.");
} else {
for (Bucket bucket : buckets) {
System.out.println("- " + bucket.getName());
}
}
// リソースを解放
ossClient.shutdown();
System.out.println("OSS client has been shut down.");
}
}
コードを実行すると、すべてのリージョンにある現在のアカウントのバケットが表示されます:
Successfully connected to OSS. Buckets under the current account:
- example-bucket
OSS client has been shut down.
クライアント設定
ClientConfiguration クラスを使用して、タイムアウト期間、リトライ、プロキシサーバーなどの OSSClient パラメーターを設定します。
カスタムドメイン名の使用
デフォルトの OSS ドメイン名は、OSS のセキュリティポリシーにより、アクセス拒否やプレビューの失敗を引き起こす可能性があります。カスタムドメイン名をバインドすることで、これらの制限を回避し、ファイルの直接プレビューを有効にし、グローバルなコンテンツアクセラレーションのための CDN 統合をサポートします。
ClientBuilderConfiguration clientBuilderConfiguration = new ClientBuilderConfiguration();
// CNAME オプションを有効にして、カスタムドメイン名によるアクセスをサポート
clientBuilderConfiguration.setSupportCname(true);
OSS ossClient = new OSSClientBuilder()
// その他の設定...
.clientConfiguration(clientBuilderConfiguration)
// エンドポイントとしてカスタムドメイン名を使用します (例: https://static.example.com)
.endpoint("https://static.example.com")
.build();
内部エンドポイントの使用
アプリケーションが Elastic Compute Service (ECS) や Container Service などの Alibaba Cloud サービス上で実行されている場合、内部エンドポイントを使用すると、無料の内部データ転送、高速化、安定性の向上が得られます。内部アクセスは、大容量ファイルのアップロード、バッチデータ処理、高頻度のアクセスに適しています。リージョンとエンドポイント。
ClientBuilderConfiguration clientBuilderConfiguration = new ClientBuilderConfiguration();
OSS ossClient = new OSSClientBuilder()
// その他の設定...
.clientConfiguration(clientBuilderConfiguration)
// 内部エンドポイントを使用します。中国 (杭州) リージョンを例として使用します。他のリージョンの場合は、実際のエンドポイントを指定してください。
.endpoint("oss-cn-hangzhou-internal.aliyuncs.com")
.build();
タイムアウト制御
ユースケースに合わせてタイムアウトパラメーターを調整します。大容量のファイル転送や不安定なネットワークの場合はタイムアウトを長くします。高同時実行性、軽量な操作の場合は、リソースを迅速に解放するために短いタイムアウトを使用します。
ClientBuilderConfiguration clientBuilderConfiguration = new ClientBuilderConfiguration();
// 許可されるオープンな HTTP 接続の最大数を設定します。デフォルトは 1024 です。
clientBuilderConfiguration.setMaxConnections(1024)
// ソケットレイヤーでのデータ転送のタイムアウト期間をミリ秒単位で設定します。デフォルトは 50000 ms です。
.setSocketTimeout(50000)
// 接続確立のタイムアウト期間をミリ秒単位で設定します。デフォルトは 50000 ms です。
.setConnectionTimeout(50000)
// 接続プールから接続を取得するためのタイムアウト期間をミリ秒単位で設定します。デフォルトでは、タイムアウト制限はありません。
.setConnectionRequestTimeout(60 * 60 * 24 * 1000)
// 接続のアイドルタイムアウト期間をミリ秒単位で設定します。接続がこの期間を超えてアイドル状態になると、閉じられます。デフォルトは 60000 ms です。
.setIdleConnectionTime(60000);
OSS ossClient = new OSSClientBuilder()
// その他の設定...
.clientConfiguration(clientBuilderConfiguration)
.build();
最大エラーリトライ回数
OSS クライアントは、失敗したリクエストをデフォルトで 3 回リトライします。高同時実行性または不安定なネットワーク環境では、setMaxErrorRetry を使用してリトライ回数を増やします。レイテンシー要件とネットワーク品質に基づいて調整してください。
ClientBuilderConfiguration clientBuilderConfiguration = new ClientBuilderConfiguration();
// 失敗したリクエストの最大リトライ回数を設定します。ネットワーク環境とビジネスニーズに基づいてこれを調整してください。
clientBuilderConfiguration.setMaxErrorRetry(5);
OSS ossClient = new OSSClientBuilder()
// その他の設定...
.clientConfiguration(clientBuilderConfiguration)
.build();
リトライポリシー
setRetryStrategy を使用してカスタムリトライポリシーを設定しないでください。カスタムポリシーは予期しない動作を引き起こす可能性があります。OSS クライアントは、さまざまなリクエストタイプに対して実績のあるリトライポリシーを使用します:
-
POST リクエスト:これらは、繰り返し送信することで発生する可能性のあるデータの不整合を避けるため、デフォルトではリトライされません。
-
POST 以外のリクエスト:以下の条件が満たされた場合、最大 3 回リトライされます。
-
次のいずれかのエラーコードで
ClientException例外が発生した場合:ConnectionTimeout、SocketTimeout、ConnectionRefused、UnknownHost、またはSocketException。 -
InvalidResponse以外のエラーコードでOSSException例外が発生した場合。 -
HTTP ステータスコード 500、502、または 503 で一時的なサーバー側のエラーが発生した場合。
-
プロキシサーバー
企業ネットワークは、多くの場合、プロキシサーバーを介してトラフィックをルーティングします。プロキシを設定すると、OSS クライアントはすべての HTTP リクエストをプロキシ経由で転送します。
ClientBuilderConfiguration clientBuilderConfiguration = new ClientBuilderConfiguration();
// ユーザーエージェントを設定します。これは HTTP の User-Agent ヘッダーです。デフォルト値は aliyun-sdk-java です。
clientBuilderConfiguration.setUserAgent("aliyun-sdk-java");
// プロキシサーバーの IP アドレスを設定します。"" を実際のプロキシサーバーの IP アドレス (例: "196.128.xxx.xxx") に置き換えます。
clientBuilderConfiguration.setProxyHost("");
// プロキシサーバーのポート (例: 8080) を設定します。
clientBuilderConfiguration.setProxyPort(8080);
// プロキシサーバー認証のユーザー名を設定します。"" を実際のユーザー名 (例: "admin") に置き換えます。
clientBuilderConfiguration.setProxyUsername("");
// プロキシサーバー認証のパスワードを設定します。"" を対応するパスワードに置き換えます。
clientBuilderConfiguration.setProxyPassword("");
OSS ossClient = new OSSClientBuilder()
// その他の設定...
.clientConfiguration(clientBuilderConfiguration)
.build();
HTTP/HTTPS プロトコル
setProtocol を使用して通信プロトコルを設定します。デフォルトは HTTP です。本番環境では、安全なデータ転送を確保し、中間者攻撃を防ぐために HTTPS を使用してください。
ClientBuilderConfiguration clientBuilderConfiguration = new ClientBuilderConfiguration();
// 安全なデータ転送を確保するために、通信プロトコルを HTTPS に設定します。
clientBuilderConfiguration.setProtocol(Protocol.HTTPS);
OSS ossClient = new OSSClientBuilder()
// その他の設定...
.clientConfiguration(clientBuilderConfiguration)
.build();
署名バージョン
Alibaba Cloud Object Storage Service (OSS) 署名バージョン 1 は、以下のスケジュールに従って段階的に廃止されます。サービスに影響が出ないよう、できるだけ早く署名バージョン 4 にアップグレードすることを推奨します。
-
2025 年 3 月 1 日以降、新規ユーザーは署名バージョン 1 を使用できなくなります。
-
2025 年 9 月 1 日以降、署名バージョン 1 は更新・メンテナンスされなくなり、新規バケットでは署名バージョン 1 を使用できなくなります。
setSignatureVersion を使用して、署名アルゴリズムのバージョンを設定できます。署名バージョン 4 を使用する場合、region パラメーターを使用して正しいリージョン ID を指定する必要があります。V4 署名アルゴリズムは、より高いセキュリティを提供します。OSS Java SDK V1 3.15.0 以降が署名バージョン 4 をサポートしています。
ClientBuilderConfiguration clientBuilderConfiguration = new ClientBuilderConfiguration();
// より高いセキュリティのために、署名アルゴリズムのバージョンを V4 に設定します。
clientBuilderConfiguration.setSignatureVersion(SignVersion.V4);
OSS ossClient = new OSSClientBuilder()
// その他の設定...
// 署名バージョン 4 を使用する場合は、リージョン ID を指定する必要があります。
.region("cn-hangzhou")
.clientConfiguration(clientBuilderConfiguration)
.build();
IP アドレスの使用
内部ネットワークアクセスや特殊なネットワーク環境では、エンドポイントとして IP アドレスを使用します。Cloud Enterprise Network (CEN)、Express Connect、専用回線、または VPN を介して接続を確立した後、直接 IP アクセスは DNS 解決をバイパスし、効率を向上させます。ルーティング設定については、「OSS の内部エンドポイントと VIP CIDR ブロック」をご参照ください。
ClientBuilderConfiguration clientBuilderConfiguration = new ClientBuilderConfiguration();
// 第 2 レベルドメイン経由での OSS へのアクセスを有効にします。この機能はデフォルトで無効になっています。
// この値は、OSS Java SDK V1 2.1.2 以前で設定する必要があります。
// バージョン 2.1.2 以降は IP アドレスを自動的に検出するため、この値は不要です。
clientBuilderConfiguration.setSLDEnabled(true);
OSS ossClient = new OSSClientBuilder()
// その他の設定...
.clientConfiguration(clientBuilderConfiguration)
// IP アドレスを使用して OSS にアクセスする場合、SSL 証明書検証の問題を避けるために HTTP プロトコルを使用します。
.endpoint("http://10.10.10.10")
.build();
CRC チェック
転送の整合性を確保するため、CRC データチェックはデフォルトで有効になっています。本番環境では CRC を有効のままにしてください。ライブプレビューストリーム、IoT デバイスデータ、低品質の監視ビデオ、信頼性の高い内部ネットワークでのバッチ転送など、軽微なデータ損失が許容されるシナリオでのみ無効にすることを検討してください。無効にする前に、データ整合性のリスクを十分に評価してください。
ClientBuilderConfiguration clientBuilderConfiguration = new ClientBuilderConfiguration();
// CRC データチェック機能を無効にします。注意して使用し、リスクを十分に評価してください。
clientBuilderConfiguration.setCrcCheckEnabled(false);
OSS ossClient = new OSSClientBuilder()
// その他の設定...
.clientConfiguration(clientBuilderConfiguration)
.build();
シングルトンパターン
シングルトンパターンを使用して OSSClient インスタンスを作成および管理します。
-
OSSClient はスレッドセーフです。シングルトンパターンを使用して単一の OSSClient インスタンスを再利用することで、頻繁な作成と破棄によるオーバーヘッドを回避できます。
-
OSSClient は内部接続プールを維持します。不要になった場合は、shutdown メソッドを呼び出してリソースを解放してください。
import com.aliyun.oss.ClientBuilderConfiguration;
import com.aliyun.oss.OSS;
import com.aliyun.oss.*;
import com.aliyun.oss.OSSClientBuilder;
import com.aliyun.oss.common.auth.CredentialsProvider;
import com.aliyun.oss.common.auth.CredentialsProviderFactory;
import com.aliyun.oss.common.comm.SignVersion;
import com.aliyun.oss.internal.OSSHeaders;
import com.aliyun.oss.model.*;
import java.io.ByteArrayInputStream;
public class OssClientSingleton {
private OssClientSingleton() {}
// 静的内部クラスでシングルトンを実装 (スレッドセーフ)
private static class SingletonHolder {
private static final OSS INSTANCE = create();
private static OSS create() {
try {
// 中国 (杭州) リージョンを例として使用します。他のリージョンの場合は、実際のエンドポイントを指定してください。
String endpoint = "https://oss-cn-hangzhou.aliyuncs.com";
// バケットが配置されているリージョンを入力します。中国 (杭州) リージョンを例として使用し、リージョンを cn-hangzhou に設定します。
String region = "cn-hangzhou";
ClientBuilderConfiguration config = new ClientBuilderConfiguration();
// V4 署名アルゴリズムの使用を明示的に宣言します。
config.setSignatureVersion(SignVersion.V4);
// 環境変数からアクセス認証情報を取得します。このサンプルコードを実行する前に、OSS_ACCESS_KEY_ID と OSS_ACCESS_KEY_SECRET 環境変数が設定されていることを確認してください。
CredentialsProvider credentialsProvider = CredentialsProviderFactory.newEnvironmentVariableCredentialsProvider();
// OSS クライアントをビルドします。
return OSSClientBuilder.create()
.endpoint(endpoint)
.credentialsProvider(credentialsProvider)
.clientConfiguration(config)
.region(region)
.build();
} catch (Exception e) {
throw new RuntimeException("Failed to initialize OSS client", e);
}
}
}
// シングルトンインスタンスを取得します。
public static OSS getInstance() {
return SingletonHolder.INSTANCE;
}
// main 関数で PutObject 操作をテストします。
public static void main(String[] args) {
// シングルトンの OSS クライアントを取得します。
OSS ossClient = OssClientSingleton.getInstance();
// バケット名 (例: examplebucket) を入力します。
String bucketName = "examplebucket";
// オブジェクトの完全なパス (バケット名を除く、例: testfolder/exampleobject.txt) を入力します。
String objectKey = "testfolder/exampleobject.txt";
try {
// 文字列を入力します。
String content = "Hello OSS";
// PutObjectRequest オブジェクトを作成します。
PutObjectRequest putObjectRequest = new PutObjectRequest(bucketName, objectKey, new ByteArrayInputStream(content.getBytes()));
// アップロード中にストレージクラスとアクセス権限を設定するには、次のサンプルコードをご参照ください。
ObjectMetadata metadata = new ObjectMetadata();
metadata.setHeader(OSSHeaders.OSS_STORAGE_CLASS, StorageClass.Standard.toString());
metadata.setObjectAcl(CannedAccessControlList.Private);
putObjectRequest.setMetadata(metadata);
// 文字列をアップロードします。
PutObjectResult result = ossClient.putObject(putObjectRequest);
// アップロード結果を出力します。
System.out.println("File uploaded successfully!");
System.out.println("ETag: " + result.getETag());
System.out.println("Request ID: " + result.getRequestId());
} catch (OSSException oe) {
System.out.println("Caught an OSSException, which means your request made it to OSS, "
+ "but was rejected with an error response for some reason.");
System.out.println("Error Message:" + oe.getErrorMessage());
System.out.println("Error Code:" + oe.getErrorCode());
System.out.println("Request ID:" + oe.getRequestId());
System.out.println("Host ID:" + oe.getHostId());
} catch (ClientException ce) {
System.out.println("Caught an ClientException, which means the client encountered "
+ "a serious internal problem while trying to communicate with OSS, "
+ "such as not being able to access the network.");
System.out.println("Error Message:" + ce.getMessage());
} finally {
// シングルトンモードでは、後続の使用に影響を与える可能性があるため、各操作後にクライアントを閉じないでください (接続を再利用するため)。
// OSSClient インスタンスが不要になった場合 (アプリケーションの終了前など)、shutdown メソッドを一度呼び出してリソースを解放します。
// ossClient.shutdown();
}
}
}
例外処理
OSS Java SDK V1 は、ClientException と OSSException の 2 種類の例外をスローします。どちらも RuntimeException を拡張したものです。
クライアント例外 (ClientException)
クライアント例外は、リクエストの構築、送信、またはデータ転送中に発生します。一般的なシナリオは次のとおりです:
-
ネットワーク接続が利用できず、リクエストをサーバーに送信できない。
-
ファイルアップロード中に IO 例外が発生する。
-
リクエストのタイムアウトや証明書検証の失敗など、基盤となるネットワーク例外が発生する。
ClientException は、リクエストが OSS サーバーに送信されなかったか、クライアント側の処理中にエラーが発生したことを意味します。ネットワーク接続とクライアント設定を確認してください。
サーバー例外 (OSSException)
サーバー例外は、リクエストが OSS に到達したが拒否されたことを意味します。OSSException は以下を提供します:
-
正確な問題特定のための詳細なエラーコードとエラーメッセージが含まれています。
-
一般的なエラーには、SignatureDoesNotMatch、AccessDenied、NoSuchKey などがあります。
-
エラーコードに基づいてこれらの例外を処理することで、プログラムの堅牢性とユーザーエクスペリエンスを大幅に向上させることができます。
これら 2 種類の例外を個別にキャッチして、エラーを正確に特定し、処理します。
// クライアント操作の作成...
try {
// ファイルのアップロード、ダウンロード、オブジェクトのリスト表示など、OSS 操作を実行します。
// これらの操作は OSS 関連の例外をスローする可能性があります。
ossClient.putObject(...);
} catch (OSSException oe) {
// OSS サーバーから返された例外をキャッチします。
// この例外は、リクエストが OSS サーバーに正常に到達したが、サーバーがリクエストを拒否した場合にスローされます。
// 一般的な原因:権限不足、不正なパラメーター、リソースが存在しないなど。
System.out.println("Caught an OSSException, which means your request made it to OSS, "
+ "but was rejected with an error response for some reason.");
// 問題の特定とデバッグのために詳細なエラー情報を出力します。
System.out.println("Error Message: " + oe.getErrorMessage());
System.out.println("Error Code: " + oe.getErrorCode());
System.out.println("Request ID: " + oe.getRequestId());
System.out.println("Host ID: " + oe.getHostId());
} catch (ClientException ce) {
// クライアント例外をキャッチします。
// この例外は、クライアントが OSS との通信中に重大な内部問題に遭遇した場合にスローされます。
// 一般的な原因:ネットワーク接続の問題、SSL 証明書の問題、DNS 解決の失敗など。
System.out.println("Caught an ClientException, which means the client encountered "
+ "a serious internal problem while trying to communicate with OSS, "
+ "such as not being able to access the network.");
// クライアント例外の詳細情報を出力します。
System.out.println("Error Message: " + ce.getMessage());
} finally {
// 操作が成功したか失敗したかに関わらず、クライアントリソースを解放します。
// これは、リソースリークや接続プールの枯渇を避けるためのベストプラクティスです。
if (ossClient != null) {
ossClient.shutdown(); // クライアントを閉じて、ネットワーク接続やその他のリソースを解放します。
}
}
サンプルコード
OSS Java SDK V1 は、バケット管理、ファイル操作、アクセス制御、暗号化転送をカバーするサンプルコードを提供します:
|
サンプルファイル |
サンプルコンテンツ |
|
|
|
|
説明
PostObject の実装は Java SDK に依存しません。 |
|
アクセス認証情報の設定
OSS は複数の認証情報初期化メソッドをサポートしています。認証ニーズに基づいて選択してください。
RAM ユーザーの AccessKey ペアを使用する
安全な環境で、頻繁な認証情報ローテーションなしで長期的な OSS アクセスが必要なアプリケーションに適しています。RAM ユーザーの AccessKey ペア (AccessKey ID と AccessKey Secret) で認証情報プロバイダーを初期化します。この方法では、手動での AccessKey ペアのメンテナンスが必要となり、セキュリティリスクが増加します。
-
Alibaba Cloud アカウント (root ユーザー) は、そのリソースに対して完全な権限を持っています。AccessKey ペアが漏洩すると、システムに重大なリスクをもたらします。Alibaba Cloud アカウントの AccessKey ペアの使用は推奨されません。代わりに、最小限の必要権限を持つ RAM ユーザーの AccessKey ペアを使用してください。
-
RAM ユーザーの AccessKey ペアを作成するには、「AccessKey ペアの作成」をご参照ください。RAM ユーザーの AccessKey ID と AccessKey Secret は、AccessKey ペアの作成時にのみ表示されます。忘れた場合は、新しい AccessKey ペアを作成して古いものを置き換える必要があります。
環境変数
-
RAM ユーザーの AccessKey ペアを使用して環境変数を設定します。
Linux
-
コマンドラインインターフェイスで次のコマンドを実行して、環境変数の設定を
~/.bashrcファイルに追加します。echo "export OSS_ACCESS_KEY_ID='YOUR_ACCESS_KEY_ID'" >> ~/.bashrc echo "export OSS_ACCESS_KEY_SECRET='YOUR_ACCESS_KEY_SECRET'" >> ~/.bashrc -
次のコマンドを実行して変更を適用します。
source ~/.bashrc -
次のコマンドを実行して、環境変数が設定されていることを確認します。
echo $OSS_ACCESS_KEY_ID echo $OSS_ACCESS_KEY_SECRET
macOS
-
ターミナルで次のコマンドを実行して、デフォルトのシェルタイプを表示します。
echo $SHELL -
デフォルトのシェルタイプに基づいて、次の操作を実行します。
Zsh
-
次のコマンドを実行して、環境変数の設定を
~/.zshrcファイルに追加します。echo "export OSS_ACCESS_KEY_ID='YOUR_ACCESS_KEY_ID'" >> ~/.zshrc echo "export OSS_ACCESS_KEY_SECRET='YOUR_ACCESS_KEY_SECRET'" >> ~/.zshrc -
次のコマンドを実行して変更を適用します。
source ~/.zshrc -
次のコマンドを実行して、環境変数が設定されていることを確認します。
echo $OSS_ACCESS_KEY_ID echo $OSS_ACCESS_KEY_SECRET
Bash
-
次のコマンドを実行して、環境変数の設定を
~/.bash_profileファイルに追加します。echo "export OSS_ACCESS_KEY_ID='YOUR_ACCESS_KEY_ID'" >> ~/.bash_profile echo "export OSS_ACCESS_KEY_SECRET='YOUR_ACCESS_KEY_SECRET'" >> ~/.bash_profile -
次のコマンドを実行して変更を適用します。
source ~/.bash_profile -
次のコマンドを実行して、環境変数が設定されていることを確認します。
echo $OSS_ACCESS_KEY_ID echo $OSS_ACCESS_KEY_SECRET
-
Windows
CMD
-
CMD で次のコマンドを実行します。
setx OSS_ACCESS_KEY_ID "YOUR_ACCESS_KEY_ID" setx OSS_ACCESS_KEY_SECRET "YOUR_ACCESS_KEY_SECRET" -
次のコマンドを実行して、環境変数が設定されていることを確認します。
echo %OSS_ACCESS_KEY_ID% echo %OSS_ACCESS_KEY_SECRET%
PowerShell
-
PowerShell で次のコマンドを実行します。
[Environment]::SetEnvironmentVariable("OSS_ACCESS_KEY_ID", "YOUR_ACCESS_KEY_ID", [EnvironmentVariableTarget]::User) [Environment]::SetEnvironmentVariable("OSS_ACCESS_KEY_SECRET", "YOUR_ACCESS_KEY_SECRET", [EnvironmentVariableTarget]::User) -
次のコマンドを実行して、環境変数が設定されていることを確認します。
[Environment]::GetEnvironmentVariable("OSS_ACCESS_KEY_ID", [EnvironmentVariableTarget]::User) [Environment]::GetEnvironmentVariable("OSS_ACCESS_KEY_SECRET", [EnvironmentVariableTarget]::User)
-
-
システム環境変数を変更した後、IDE、コマンドラインインターフェイス、その他のデスクトップアプリケーション、バックエンドサービスなど、開発環境を再起動またはリフレッシュして、最新のシステム環境変数が正常にロードされるようにします。
-
環境変数を使用して認証情報を渡します。
import com.aliyun.oss.ClientBuilderConfiguration; import com.aliyun.oss.OSS; import com.aliyun.oss.OSSClientBuilder; import com.aliyun.oss.common.auth.CredentialsProviderFactory; import com.aliyun.oss.common.auth.EnvironmentVariableCredentialsProvider; import com.aliyun.oss.common.comm.SignVersion; public class AkDemoTest { public static void main(String[] args) throws Exception { // 環境変数から認証情報を取得します。 EnvironmentVariableCredentialsProvider credentialsProvider = CredentialsProviderFactory.newEnvironmentVariableCredentialsProvider(); // 後続の操作で credentialsProvider を使用します... ClientBuilderConfiguration clientBuilderConfiguration = new ClientBuilderConfiguration(); clientBuilderConfiguration.setSignatureVersion(SignVersion.V4); // OSSClient インスタンスを作成します。 // OSSClient インスタンスが不要になった場合は、shutdown メソッドを呼び出してリソースを解放します。 OSS ossClient = OSSClientBuilder.create() .endpoint("endpoint") .credentialsProvider(credentialsProvider) .clientConfiguration(clientBuilderConfiguration) .region("region") .build(); ossClient.shutdown(); } }
静的認証情報
以下のサンプルコードは、アクセス認証情報をハードコーディングし、使用する AccessKey ペアを明示的に設定する方法を示しています。
本番環境のアプリケーションにアクセス認証情報を埋め込まないでください。この方法はテスト目的でのみ使用します。
import com.aliyun.oss.ClientBuilderConfiguration;
import com.aliyun.oss.OSS;
import com.aliyun.oss.OSSClientBuilder;
import com.aliyun.oss.common.auth.CredentialsProvider;
import com.aliyun.oss.common.auth.DefaultCredentialProvider;
import com.aliyun.oss.common.comm.SignVersion;
public class AkDemoTest {
public static void main(String[] args) throws Exception {
// RAM ユーザーの AccessKey ID と AccessKey Secret を入力します。
String accessKeyId = "yourAccessKeyID";
String accessKeySecret = "yourAccessKeySecret";
// DefaultCredentialProvider メソッドを使用して、AccessKey ID と AccessKey Secret を直接設定します。
CredentialsProvider credentialsProvider = new DefaultCredentialProvider(accessKeyId, accessKeySecret);
// credentialsProvider を使用してクライアントを初期化します。
ClientBuilderConfiguration clientBuilderConfiguration = new ClientBuilderConfiguration();
// V4 署名アルゴリズムの使用を明示的に宣言します。
clientBuilderConfiguration.setSignatureVersion(SignVersion.V4);
// OSSClient インスタンスを作成します。
// OSSClient インスタンスが不要になった場合は、shutdown メソッドを呼び出してリソースを解放します。
OSS ossClient = OSSClientBuilder.create()
.endpoint("endpoint")
.credentialsProvider(credentialsProvider)
.clientConfiguration(clientBuilderConfiguration)
.region("region")
.build();
ossClient.shutdown();
}
}
STS トークンを使用する
OSS への一時的なアクセスが必要なアプリケーションに適しています。STS からの一時的な認証情報 (AccessKey ID、AccessKey Secret、およびセキュリティトークン) で認証情報プロバイダーを初期化します。繰り返しアクセスするには、STS トークンを手動でリフレッシュする必要があります。
-
OpenAPI を介して迅速に STS トークンを取得するには、「AssumeRole - RAM ロールの一時的な ID 認証情報を取得する」をご参照ください。
-
SDK を使用して STS トークンを取得するには、「STS トークンを使用して OSS にアクセスする」をご参照ください。
-
STS トークンを生成する際には、有効期限を指定する必要があります。トークンは有効期限が切れると無効になり、使用できなくなります。
-
STS サービスエンドポイントのリストについては、「サービスエンドポイント」をご参照ください。
環境変数
-
一時的な ID 認証情報を使用して環境変数を設定します。
Mac OS/Linux/UNIX
重要-
ここでは、RAM ユーザーの AccessKey ペアではなく、STS サービスから取得した一時的な ID 認証情報 (AccessKey ID、AccessKey Secret、およびセキュリティトークン) を使用することに注意してください。
-
STS サービスから取得した AccessKey ID は、「STS」で始まることに注意してください (例:「STS.****************」)。
export OSS_ACCESS_KEY_ID=<STS_ACCESS_KEY_ID> export OSS_ACCESS_KEY_SECRET=<STS_ACCESS_KEY_SECRET> export OSS_SESSION_TOKEN=<STS_SECURITY_TOKEN>Windows
重要-
ここでは、RAM ユーザーの AccessKey ペア (AccessKey ID と AccessKey Secret) ではなく、STS サービスから取得した一時的な ID 認証情報 (AccessKey ID、AccessKey Secret、およびセキュリティトークン) を使用することに注意してください。
-
STS サービスから取得した AccessKey ID は、「STS」で始まることに注意してください (例:「STS.****************」)。
set OSS_ACCESS_KEY_ID=<STS_ACCESS_KEY_ID> set OSS_ACCESS_KEY_SECRET=<STS_ACCESS_KEY_SECRET> set OSS_SESSION_TOKEN=<STS_SECURITY_TOKEN> -
-
環境変数を介して認証情報を渡します。
import com.aliyun.oss.ClientBuilderConfiguration; import com.aliyun.oss.OSS; import com.aliyun.oss.OSSClientBuilder; import com.aliyun.oss.common.auth.CredentialsProviderFactory; import com.aliyun.oss.common.auth.EnvironmentVariableCredentialsProvider; import com.aliyun.oss.common.comm.SignVersion; public class StsDemoTest { public static void main(String[] args) throws Exception { // 環境変数から認証情報を取得します。 EnvironmentVariableCredentialsProvider credentialsProvider = CredentialsProviderFactory.newEnvironmentVariableCredentialsProvider(); // credentialsProvider を使用してクライアントを初期化します。 ClientBuilderConfiguration clientBuilderConfiguration = new ClientBuilderConfiguration(); // V4 署名アルゴリズムの使用を明示的に宣言します。 clientBuilderConfiguration.setSignatureVersion(SignVersion.V4); // OSSClient インスタンスを作成します。 // OSSClient インスタンスが不要になった場合は、shutdown メソッドを呼び出してリソースを解放します。 OSS ossClient = OSSClientBuilder.create() .endpoint("endpoint") .credentialsProvider(credentialsProvider) .clientConfiguration(clientBuilderConfiguration) .region("region") .build(); ossClient.shutdown(); } }
静的認証情報
アプリケーションに認証情報をハードコーディングし、使用する一時的なアクセスキーを明示的に設定できます。
import com.aliyun.oss.ClientBuilderConfiguration;
import com.aliyun.oss.OSS;
import com.aliyun.oss.OSSClientBuilder;
import com.aliyun.oss.common.auth.CredentialsProvider;
import com.aliyun.oss.common.auth.DefaultCredentialProvider;
import com.aliyun.oss.common.comm.SignVersion;
public class StsDemoTest {
public static void main(String[] args) throws Exception {
// これを STS サービスから取得した一時的な AccessKey ID、AccessKey Secret、およびセキュリティトークンに設定します。RAM ユーザーの認証情報ではありません。
// STS サービスから取得した AccessKey ID は、以下のように「STS」で始まることに注意してください。
String accessKeyId = "STS.****************";
String accessKeySecret = "yourAccessKeySecret";
String stsToken= "yourSecurityToken";
// DefaultCredentialProvider メソッドを使用して、AccessKey ID と AccessKey Secret を直接設定します。
CredentialsProvider credentialsProvider = new DefaultCredentialProvider(accessKeyId, accessKeySecret, stsToken);
// credentialsProvider を使用してクライアントを初期化します。
ClientBuilderConfiguration clientBuilderConfiguration = new ClientBuilderConfiguration();
// V4 署名アルゴリズムの使用を明示的に宣言します。
clientBuilderConfiguration.setSignatureVersion(SignVersion.V4);
// OSSClient インスタンスを作成します。
// OSSClient インスタンスが不要になった場合は、shutdown メソッドを呼び出してリソースを解放します。
OSS ossClient = OSSClientBuilder.create()
.endpoint("endpoint")
.credentialsProvider(credentialsProvider)
.clientConfiguration(clientBuilderConfiguration)
.region("region")
.build();
ossClient.shutdown();
}
}
RAMRoleARN を使用する
クロスアカウントアクセスなど、OSS への認可アクセスが必要なアプリケーションに適しています。RAM ロールの ARN を指定して認証情報プロバイダーを初期化します。SDK は AssumeRole API を呼び出すことで、STS トークンを自動的に取得およびリフレッシュします。policy パラメーターを使用して、RAM ロールをより少ない権限に制限することもできます。
-
Alibaba Cloud アカウント (root ユーザー) は、そのリソースに対して完全な権限を持っています。AccessKey ペアが漏洩すると、システムに重大なリスクをもたらします。Alibaba Cloud アカウントの AccessKey ペアの使用は推奨されません。代わりに、最小限の必要権限を持つ RAM ユーザーの AccessKey ペアを使用してください。
-
RAM ユーザーの AccessKey ペアを作成するには、「AccessKey ペアの作成」をご参照ください。RAM ユーザーの AccessKey ID と AccessKey Secret は、AccessKey ペアの作成時にのみ表示されます。速やかに保存する必要があります。忘れた場合は、新しい AccessKey ペアを作成して古いものを置き換える必要があります。
-
RAMRoleARN を取得するには、「RAM ロールの作成」をご参照ください。
-
認証情報の依存関係を追加します。
<!-- https://mvnrepository.com/artifact/com.aliyun/credentials-java --> <dependency> <groupId>com.aliyun</groupId> <artifactId>credentials-java</artifactId> <version>LATEST</version> </dependency> -
AccessKey ペアと RAMRoleARN をアクセス認証情報として設定します。
import com.aliyun.credentials.models.CredentialModel; import com.aliyun.oss.ClientBuilderConfiguration; import com.aliyun.oss.OSS; import com.aliyun.oss.OSSClientBuilder; import com.aliyun.oss.common.auth.Credentials; import com.aliyun.oss.common.auth.CredentialsProvider; import com.aliyun.oss.common.auth.DefaultCredentials; import com.aliyun.oss.common.comm.SignVersion; public class RamRoleArnAkDemoTest { public static void main(String[] args) { com.aliyun.credentials.models.Config config = new com.aliyun.credentials.models.Config(); // アクセス認証情報の種類。ram_role_arn に設定します。 config.setType("ram_role_arn"); // 引き受ける RAM ロールの ARN。例:acs:ram::123456789012****:role/adminrole。ALIBABA_CLOUD_ROLE_ARN 環境変数を介して RoleArn を設定できます。 config.setRoleArn("<RoleArn>"); // 環境変数から AccessKey ID を取得します。 config.setAccessKeyId(System.getenv().get("ALIBABA_CLOUD_ACCESS_KEY_ID")); // 環境変数から AccessKey Secret を取得します。 config.setAccessKeySecret(System.getenv().get("ALIBABA_CLOUD_ACCESS_KEY_SECRET")); // ロールセッションの名前。ALIBABA_CLOUD_ROLE_SESSION_NAME 環境変数を介して RoleSessionName を設定できます。 config.setRoleName("<RoleSessionName>"); // より小さい権限ポリシーを設定します。これはオプションです。例:{"Statement": [{"Action": ["*"],"Effect": "Allow","Resource": ["*"]}],"Version":"1"} config.setPolicy("<Policy>"); // ロールセッションの有効期間を設定します。これはオプションです。 config.setRoleSessionExpiration(3600); final com.aliyun.credentials.Client credentialsClient = new com.aliyun.credentials.Client(config); CredentialsProvider credentialsProvider = new CredentialsProvider(){ @Override public void setCredentials(Credentials credentials) { } @Override public Credentials getCredentials() { CredentialModel credential = credentialsClient.getCredential(); return new DefaultCredentials(credential.getAccessKeyId(), credential.getAccessKeySecret(), credential.getSecurityToken()); } }; // credentialsProvider を使用してクライアントを初期化します。 ClientBuilderConfiguration clientBuilderConfiguration = new ClientBuilderConfiguration(); // V4 署名アルゴリズムの使用を明示的に宣言します。 clientBuilderConfiguration.setSignatureVersion(SignVersion.V4); // OSSClient インスタンスを作成します。 // OSSClient インスタンスが不要になった場合は、shutdown メソッドを呼び出してリソースを解放します。 OSS ossClient = OSSClientBuilder.create() .endpoint("endpoint") .credentialsProvider(credentialsProvider) .clientConfiguration(clientBuilderConfiguration) .region("region") .build(); ossClient.shutdown(); } }
ECSRAMRole を使用する
ECS インスタンス、ECI インスタンス、または Container Service for Kubernetes (ACK) ワーカーノード上のアプリケーションに適しています。インスタンスに RAM ロールをアタッチすることで、ACK または ECS 内で STS トークンが自動的に取得およびリフレッシュされ、手動での認証情報管理が不要になります。ECSRAMRole を取得するには、「RAM ロールの作成」をご参照ください。ロールをアタッチするには、「インスタンス RAM ロール」をご参照ください。
-
認証情報の依存関係を追加します。
<!-- https://mvnrepository.com/artifact/com.aliyun/credentials-java --> <dependency> <groupId>com.aliyun</groupId> <artifactId>credentials-java</artifactId> <version>LATEST</version> </dependency> -
ECSRAMRole をアクセス認証情報として設定します。
import com.aliyun.credentials.models.CredentialModel; import com.aliyun.oss.ClientBuilderConfiguration; import com.aliyun.oss.OSS; import com.aliyun.oss.OSSClientBuilder; import com.aliyun.oss.common.auth.Credentials; import com.aliyun.oss.common.auth.CredentialsProvider; import com.aliyun.oss.common.auth.DefaultCredentials; import com.aliyun.oss.common.comm.SignVersion; public class EcsRamRoleDemoTest { public static void main(String[] args) { com.aliyun.credentials.models.Config config = new com.aliyun.credentials.models.Config(); // アクセス認証情報の種類。ecs_ram_role に設定します。 config.setType("ecs_ram_role"); // ECS インスタンスに割り当てられた RAM ロールの名前。 config.setRoleName("<RoleName>"); final com.aliyun.credentials.Client credentialsClient = new com.aliyun.credentials.Client(config); CredentialsProvider credentialsProvider = new CredentialsProvider(){ @Override public void setCredentials(Credentials credentials) { } @Override public Credentials getCredentials() { CredentialModel credential = credentialsClient.getCredential(); return new DefaultCredentials(credential.getAccessKeyId(), credential.getAccessKeySecret(), credential.getSecurityToken()); } }; // credentialsProvider を使用してクライアントを初期化します。 ClientBuilderConfiguration clientBuilderConfiguration = new ClientBuilderConfiguration(); // V4 署名アルゴリズムの使用を明示的に宣言します。 clientBuilderConfiguration.setSignatureVersion(SignVersion.V4); // OSSClient インスタンスを作成します。 // OSSClient インスタンスが不要になった場合は、shutdown メソッドを呼び出してリソースを解放します。 OSS ossClient = OSSClientBuilder.create() .endpoint("endpoint") .credentialsProvider(credentialsProvider) .clientConfiguration(clientBuilderConfiguration) .region("region") .build(); ossClient.shutdown(); } }
OIDCRoleARN を使用する
ACK でワーカーノードの RAM ロールを設定すると、対応するノード上の Pod 内のアプリケーションは、ECS にデプロイされたアプリケーションと同様に、グローバルメタサービスを介してアタッチされたロールの STS トークンを取得できます。ただし、信頼できないアプリケーションがコンテナクラスターにデプロイされている場合 (たとえば、コードが公開されていない顧客から提出されたアプリケーション)、これらのアプリケーションがグローバルメタサービスを介してワーカーノードにアタッチされたインスタンス RAM ロールの STS トークンを取得することを望まない場合があります。クラウドリソースのセキュリティに影響を与えることなく、これらの信頼できないアプリケーションが必要な STS トークンを安全に取得し、アプリケーションレベルの権限最小化を実現するには、RAM Roles for Service Accounts (RRSA) 機能を使用できます。このメソッドの基盤となる実装は、STS トークンに基づいています。Alibaba Cloud コンテナクラスターは、さまざまなアプリケーション Pod に対して対応するサービスアカウント OIDC トークンファイルを作成およびマウントし、関連する設定情報を環境変数に注入します。SDK は、環境変数からの設定情報を使用して STS サービスの AssumeRoleWithOIDC API 操作を呼び出すことにより、バインドされたロールの STS トークンを取得します。この方法では、AccessKey ペアや STS トークンを手動で維持するリスクがなくなります。詳細については、「RRSA を介して ServiceAccount の RAM 権限を設定し、Pod の権限隔離を実現する」をご参照ください。
-
認証情報の依存関係を追加します。
<!-- https://mvnrepository.com/artifact/com.aliyun/credentials-java --> <dependency> <groupId>com.aliyun</groupId> <artifactId>credentials-java</artifactId> <version>LATEST</version> </dependency> -
OIDC RAM ロールをアクセス認証情報として設定します。
import com.aliyun.credentials.models.CredentialModel; import com.aliyun.oss.ClientBuilderConfiguration; import com.aliyun.oss.OSS; import com.aliyun.oss.OSSClientBuilder; import com.aliyun.oss.common.auth.Credentials; import com.aliyun.oss.common.auth.CredentialsProvider; import com.aliyun.oss.common.auth.DefaultCredentials; import com.aliyun.oss.common.comm.SignVersion; public class OidcRoleArnDemoTest { public static void main(String[] args) { com.aliyun.credentials.models.Config config = new com.aliyun.credentials.models.Config(); // Credential の種類を指定します。oidc_role_arn に設定します。 config.setType("oidc_role_arn"); // RAM ロールの ARN。ALIBABA_CLOUD_ROLE_ARN 環境変数を介して RoleArn を設定できます。 config.setRoleArn("<RoleArn>"); // OIDC プロバイダーの ARN。ALIBABA_CLOUD_OIDC_PROVIDER_ARN 環境変数を介して OidcProviderArn を設定できます。 config.setOidcProviderArn("<OidcProviderArn>"); // OIDC トークンファイルのパス。ALIBABA_CLOUD_OIDC_TOKEN_FILE 環境変数を介して OidcTokenFilePath を設定できます。 config.setOidcTokenFilePath("<OidcTokenFilePath>"); // ロールセッションの名前。ALIBABA_CLOUD_ROLE_SESSION_NAME 環境変数を介して RoleSessionName を設定できます。 config.setRoleSessionName("<RoleSessionName>"); // より小さい権限ポリシーを設定します。これはオプションです。例:{"Statement": [{"Action": ["*"],"Effect": "Allow","Resource": ["*"]}],"Version":"1"} config.setPolicy("<Policy>"); // セッションの有効期限を設定します。 config.setRoleSessionExpiration(3600); final com.aliyun.credentials.Client credentialsClient = new com.aliyun.credentials.Client(config); CredentialsProvider credentialsProvider = new CredentialsProvider(){ @Override public void setCredentials(Credentials credentials) { } @Override public Credentials getCredentials() { CredentialModel credential = credentialsClient.getCredential(); return new DefaultCredentials(credential.getAccessKeyId(), credential.getAccessKeySecret(), credential.getSecurityToken()); } }; // credentialsProvider を使用してクライアントを初期化します。 ClientBuilderConfiguration clientBuilderConfiguration = new ClientBuilderConfiguration(); // V4 署名アルゴリズムの使用を明示的に宣言します。 clientBuilderConfiguration.setSignatureVersion(SignVersion.V4); // OSSClient インスタンスを作成します。 // OSSClient インスタンスが不要になった場合は、shutdown メソッドを呼び出してリソースを解放します。 OSS ossClient = OSSClientBuilder.create() .endpoint("endpoint") .credentialsProvider(credentialsProvider) .clientConfiguration(clientBuilderConfiguration) .region("region") .build(); ossClient.shutdown(); } }
Function Compute コンテキストから認証情報を使用する
この方法は、Function Compute にデプロイされたアプリケーションの関数向けです。Function Compute コンテキストからの認証情報で認証情報プロバイダーを初期化できます。基盤となる実装は STS トークンに基づいています。Function Compute は、関数に設定されたサービスロールを引き受けることで STS トークンを取得し、その STS トークンをコンテキストの Credentials パラメーターを介してアプリケーションに渡します。この STS トークンは 36 時間有効で、変更できません。関数の最大実行時間は 24 時間なので、関数実行中に STS トークンが期限切れになることはなく、リフレッシュを考慮する必要はありません。この方法では、AccessKey ペアや STS トークンを手動で維持するリスクがなくなります。Function Compute に OSS へのアクセス権限を付与するには、「関数ロールを使用して Function Compute に他の Alibaba Cloud サービスへのアクセス権限を付与する」をご参照ください。
-
Function Compute コンテキストの依存関係を追加します。
<!-- https://mvnrepository.com/artifact/com.aliyun.fc.runtime/fc-java-core --> <dependency> <groupId>com.aliyun.fc.runtime</groupId> <artifactId>fc-java-core</artifactId> <version>1.4.1</version> </dependency> -
Function Compute コンテキストからの認証情報で認証情報プロバイダーを初期化します。
import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import com.aliyun.fc.runtime.Context; import com.aliyun.fc.runtime.Credentials; import com.aliyun.fc.runtime.StreamRequestHandler; import com.aliyun.oss.ClientBuilderConfiguration; import com.aliyun.oss.OSS; import com.aliyun.oss.OSSClientBuilder; import com.aliyun.oss.common.auth.*; import com.aliyun.oss.common.comm.SignVersion; public class App implements StreamRequestHandler { @Override public void handleRequest( InputStream inputStream, OutputStream outputStream, Context context) throws IOException { // キー情報を取得します。実行前に、関数が属するサービスにロール情報が設定されており、そのロールが必要な OSS 権限を持っていることを確認してください。AliyunFCDefaultRole ロールの使用を推奨します。 Credentials creds = context.getExecutionCredentials(); // 取得した認証情報を使用して、認証情報プロバイダーインスタンスを作成します。 CredentialsProvider credentialsProvider = new DefaultCredentialProvider(creds.getAccessKeyId(), creds.getAccessKeySecret(), creds.getSecurityToken()); // credentialsProvider を使用してクライアントを初期化します。 ClientBuilderConfiguration clientBuilderConfiguration = new ClientBuilderConfiguration(); // V4 署名アルゴリズムの使用を明示的に宣言します。 clientBuilderConfiguration.setSignatureVersion(SignVersion.V4); // OSSClient インスタンスを作成します。 // OSSClient インスタンスが不要になった場合は、shutdown メソッドを呼び出してリソースを解放します。 OSS ossClient = OSSClientBuilder.create() .endpoint("endpoint") .credentialsProvider(credentialsProvider) .clientConfiguration(clientBuilderConfiguration) .region("region") .build(); ossClient.shutdown(); outputStream.write(new String("done").getBytes()); } }
CredentialsURI を使用する
柔軟な認証情報管理のために外部システムから認証情報を取得するアプリケーションに適しています。STS トークンを返す URI で認証情報プロバイダーを初期化します。SDK は指定された URI からトークンを自動的に取得およびリフレッシュします。
-
SDK が STS トークンを正しく解析して使用するためには、URI は次の応答プロトコルに従う必要があります:
-
応答ステータスコード:200
-
応答本文の構造:
{ "Code": "Success", "AccessKeySecret": "AccessKeySecret", "AccessKeyId": "AccessKeyId", "Expiration": "2021-09-26T03:46:38Z", "SecurityToken": "SecurityToken" }
-
-
認証情報の依存関係を追加します。
<!-- https://mvnrepository.com/artifact/com.aliyun/credentials-java --> <dependency> <groupId>com.aliyun</groupId> <artifactId>credentials-java</artifactId> <version>LATEST</version> </dependency> -
CredentialsURI をアクセス認証情報として設定します。
import com.aliyun.credentials.models.CredentialModel; import com.aliyun.oss.ClientBuilderConfiguration; import com.aliyun.oss.OSS; import com.aliyun.oss.OSSClientBuilder; import com.aliyun.oss.common.auth.Credentials; import com.aliyun.oss.common.auth.CredentialsProvider; import com.aliyun.oss.common.auth.DefaultCredentials; import com.aliyun.oss.common.comm.SignVersion; public class CredentialsUriDemoTest { public static void main(String[] args) { com.aliyun.credentials.models.Config config = new com.aliyun.credentials.models.Config(); // アクセス認証情報の種類。credentials_uri に設定します。 config.setType("credentials_uri"); // 認証情報の URI。これは STS トークンを生成するサーバーのアドレスで、http://local_or_remote_uri/ の形式です。ALIBABA_CLOUD_CREDENTIALS_URI 環境変数を介して CredentialsUri を設定できます。 config.setCredentialsUri("<CredentialsUri>"); final com.aliyun.credentials.Client credentialsClient = new com.aliyun.credentials.Client(config); CredentialsProvider credentialsProvider = new CredentialsProvider(){ @Override public void setCredentials(Credentials credentials) { } @Override public Credentials getCredentials() { CredentialModel credential = credentialsClient.getCredential(); return new DefaultCredentials(credential.getAccessKeyId(), credential.getAccessKeySecret(), credential.getSecurityToken()); } }; // credentialsProvider を使用してクライアントを初期化します。 ClientBuilderConfiguration clientBuilderConfiguration = new ClientBuilderConfiguration(); // V4 署名アルゴリズムの使用を明示的に宣言します。 clientBuilderConfiguration.setSignatureVersion(SignVersion.V4); // OSSClient インスタンスを作成します。 // OSSClient インスタンスが不要になった場合は、shutdown メソッドを呼び出してリソースを解放します。 OSS ossClient = OSSClientBuilder.create() .endpoint("endpoint") .credentialsProvider(credentialsProvider) .clientConfiguration(clientBuilderConfiguration) .region("region") .build(); ossClient.shutdown(); } }
自動ローテーション AccessKey ペアを使用する
AccessKey 漏洩リスクのある環境で長期的な OSS アクセスが必要なアプリケーションに適しています。ClientKey で認証情報プロバイダーを初期化します。Key Management Service (KMS) は、管理対象の RAM ユーザーの AccessKey ペアを自動的にローテーションし、静的な認証情報を動的にすることで漏洩リスクを低減します。KMS は即時ローテーションもサポートしています。ClientKey を取得するには、「アプリケーションアクセスポイントの作成」をご参照ください。
-
認証情報クライアントの依存関係を追加します。
<!-- https://mvnrepository.com/artifact/com.aliyun/alibabacloud-secretsmanager-client --> <dependency> <groupId>com.aliyun</groupId> <artifactId>alibabacloud-secretsmanager-client</artifactId> <version>1.3.7</version> </dependency> <!-- https://mvnrepository.com/artifact/com.aliyun/aliyun-java-sdk-core --> <dependency> <groupId>com.aliyun</groupId> <artifactId>aliyun-java-sdk-core</artifactId> <version>4.7.0</version> </dependency> -
設定ファイル
secretsmanager.propertiesを作成します。# アクセス認証情報の種類、client_key に固定 credentials_type=client_key # Client Key の読み取り用復号パスワード:環境変数またはファイルからの読み取りをサポート、いずれか一方を設定 client_key_password_from_env_variable=<your client key private key password environment variable name> client_key_password_from_file_path=<your client key private key password file path> # Client Key の秘密鍵ファイルのパス client_key_private_key_path=<your client key private key file path> # 関連する KMS サービスのリージョン cache_client_region_id=[{"regionId":"<regionId>"}] -
設定ファイルを使用して認証情報を渡します。
import com.aliyun.oss.ClientBuilderConfiguration; import com.aliyun.oss.OSS; import com.aliyun.oss.OSSClientBuilder; import com.aliyun.oss.common.auth.Credentials; import com.aliyun.oss.common.auth.CredentialsProvider; import com.aliyun.oss.common.auth.DefaultCredentials; import com.aliyun.oss.common.comm.SignVersion; import com.aliyuncs.kms.secretsmanager.client.SecretCacheClient; import com.aliyuncs.kms.secretsmanager.client.SecretCacheClientBuilder; import com.aliyuncs.kms.secretsmanager.client.exception.CacheSecretException; import com.aliyuncs.kms.secretsmanager.client.model.SecretInfo; import org.codehaus.jettison.json.JSONException; import org.codehaus.jettison.json.JSONObject; public class ClientKeyDemoTest { public static void main(String[] args) throws CacheSecretException { final SecretCacheClient client = SecretCacheClientBuilder.newClient(); CredentialsProvider credentialsProvider = new CredentialsProvider() { @Override public void setCredentials(Credentials credentials) { } @Override public Credentials getCredentials() { try { SecretInfo secretInfo = client.getSecretInfo("<secretName>"); JSONObject jsonObject = new JSONObject(secretInfo.getSecretValue()); String accessKeyId = jsonObject.getString("AccessKeyId"); String accessKeySecret = jsonObject.getString("AccessKeySecret"); return new DefaultCredentials(accessKeyId, accessKeySecret); } catch (CacheSecretException | JSONException e) { return null; } } }; // credentialsProvider を使用してクライアントを初期化します。 ClientBuilderConfiguration clientBuilderConfiguration = new ClientBuilderConfiguration(); // V4 署名アルゴリズムの使用を明示的に宣言します。 clientBuilderConfiguration.setSignatureVersion(SignVersion.V4); // OSSClient インスタンスを作成します。 // OSSClient インスタンスが不要になった場合は、shutdown メソッドを呼び出してリソースを解放します。 OSS ossClient = OSSClientBuilder.create() .endpoint("endpoint") .credentialsProvider(credentialsProvider) .clientConfiguration(clientBuilderConfiguration) .region("region") .build(); ossClient.shutdown(); } }
カスタムアクセス認証情報を使用する
前述の認証情報設定方法のいずれも要件を満たさない場合は、Credential Providers インターフェイスを実装することで、認証情報プロバイダーをカスタマイズできます。基盤となる実装が STS トークンに基づいている場合は、認証情報の更新をサポートする必要があることに注意してください。
import com.aliyun.oss.ClientBuilderConfiguration;
import com.aliyun.oss.OSS;
import com.aliyun.oss.OSSClientBuilder;
import com.aliyun.oss.common.auth.Credentials;
import com.aliyun.oss.common.auth.CredentialsProvider;
import com.aliyun.oss.common.auth.DefaultCredentials;
import com.aliyun.oss.common.comm.SignVersion;
public class CustomCredentialProviderDemoTest {
public static void main(String[] args) {
CredentialsProvider credentialsProvider = new CredentialsProvider(){
// 変数を初期化
String accessKeyId = null;
// 変数を初期化
String accessKeySecrect = null;
// 変数を初期化
// String token = null;
@Override
public void setCredentials(Credentials credentials) {
}
@Override
public Credentials getCredentials() {
//TODO
//アクセス認証情報を取得するメソッドをカスタマイズします。
// 長期的な認証情報を返す:access_key_id, access_key_secrect
return new DefaultCredentials(accessKeyId, accessKeySecrect);
// 一時的な認証情報を返す:access_key_id, access_key_secrect, token
// 一時的な認証情報の場合、有効期限に基づいてリフレッシュする必要があります。
// return new DefaultCredentials(accessKeyId, accessKeySecrect, token);
}
};
// credentialsProvider を使用してクライアントを初期化します。
ClientBuilderConfiguration clientBuilderConfiguration = new ClientBuilderConfiguration();
// V4 署名アルゴリズムの使用を明示的に宣言します。
clientBuilderConfiguration.setSignatureVersion(SignVersion.V4);
// OSSClient インスタンスを作成します。
// OSSClient インスタンスが不要になった場合は、shutdown メソッドを呼び出してリソースを解放します。
OSS ossClient = OSSClientBuilder.create()
.endpoint("endpoint")
.credentialsProvider(credentialsProvider)
.clientConfiguration(clientBuilderConfiguration)
.region("region")
.build();
ossClient.shutdown();
}
}
デフォルトの認証情報チェーンを使用する
認証情報クライアントをパラメーターなしで初期化すると、SDK はデフォルトの認証情報チェーンを使用します。認証情報チェーンのロジックについては、「デフォルトの認証情報チェーン」をご参照ください。
-
認証情報の依存関係を追加します。
<!-- https://mvnrepository.com/artifact/com.aliyun/credentials-java --> <dependency> <groupId>com.aliyun</groupId> <artifactId>credentials-java</artifactId> <version>LATEST</version> </dependency> -
Credentials をアクセス認証情報として設定します。
import com.aliyun.credentials.models.CredentialModel; import com.aliyun.oss.*; import com.aliyun.oss.common.auth.Credentials; import com.aliyun.oss.common.auth.CredentialsProvider; import com.aliyun.oss.common.auth.DefaultCredentials; import com.aliyun.oss.common.comm.SignVersion; public class Demo { public static void main(String[] args) { com.aliyun.credentials.Client credentialsClient = new com.aliyun.credentials.Client(); CredentialsProvider credentialsProvider = new CredentialsProvider(){ @Override public void setCredentials(Credentials credentials) { } @Override public Credentials getCredentials() { CredentialModel credential = credentialsClient.getCredential(); return new DefaultCredentials(credential.getAccessKeyId(), credential.getAccessKeySecret(), credential.getSecurityToken()); } }; ClientBuilderConfiguration clientBuilderConfiguration = new ClientBuilderConfiguration(); // V4 署名アルゴリズムの使用を明示的に宣言します。 clientBuilderConfiguration.setSignatureVersion(SignVersion.V4); // credentialsProvider を使用してクライアントを初期化します。 // OSSClient インスタンスを作成します。 // OSSClient インスタンスが不要になった場合は、shutdown メソッドを呼び出してリソースを解放します。 OSS ossClient = OSSClientBuilder.create() .endpoint("endpoint") .credentialsProvider(credentialsProvider) .clientConfiguration(clientBuilderConfiguration) .region("region") .build(); ossClient.shutdown(); } }
よくある質問
パッケージの競合
-
原因
OSS Java SDK V1 を使用しているときに、以下のようなエラーが発生した場合、プロジェクトでパッケージの競合が発生していることを示します。
Exception in thread "main" java.lang.NoClassDefFoundError: org/apache/http/ssl/TrustStrategy at com.aliyun.oss.OSSClient.<init>(OSSClient.java:268) at com.aliyun.oss.OSSClient.<init>(OSSClient.java:193) at com.aliyun.oss.demo.HelloOSS.main(HelloOSS.java:77) Caused by: java.lang.ClassNotFoundException: org.apache.http.ssl.TrustStrategy at java.net.URLClassLoader$1.run(URLClassLoader.java:366) at java.net.URLClassLoader$1.run(URLClassLoader.java:355) at java.security.AccessController.doPrivileged(Native Method) at java.net.URLClassLoader.findClass(URLClassLoader.java:354) at java.lang.ClassLoader.loadClass(ClassLoader.java:425) at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:308) at java.lang.ClassLoader.loadClass(ClassLoader.java:358) ... 3 moreまたは
Exception in thread "main" java.lang.NoSuchFieldError: INSTANCE at org.apache.http.impl.io.DefaultHttpRequestWriterFactory.<init>(DefaultHttpRequestWriterFactory.java:52) at org.apache.http.impl.io.DefaultHttpRequestWriterFactory.<init>(DefaultHttpRequestWriterFactory.java:56) at org.apache.http.impl.io.DefaultHttpRequestWriterFactory.<clinit>(DefaultHttpRequestWriterFactory.java:46) at org.apache.http.impl.conn.ManagedHttpClientConnectionFactory.<init>(ManagedHttpClientConnectionFactory.java:82) at org.apache.http.impl.conn.ManagedHttpClientConnectionFactory.<init>(ManagedHttpClientConnectionFactory.java:95) at org.apache.http.impl.conn.ManagedHttpClientConnectionFactory.<init>(ManagedHttpClientConnectionFactory.java:104) at org.apache.http.impl.conn.ManagedHttpClientConnectionFactory.<clinit>(ManagedHttpClientConnectionFactory.java:62) at org.apache.http.impl.conn.PoolingHttpClientConnectionManager$InternalConnectionFactory.<init>(PoolingHttpClientConnectionManager.java:572) at org.apache.http.impl.conn.PoolingHttpClientConnectionManager.<init>(PoolingHttpClientConnectionManager.java:174) at org.apache.http.impl.conn.PoolingHttpClientConnectionManager.<init>(PoolingHttpClientConnectionManager.java:158) at org.apache.http.impl.conn.PoolingHttpClientConnectionManager.<init>(PoolingHttpClientConnectionManager.java:149) at org.apache.http.impl.conn.PoolingHttpClientConnectionManager.<init>(PoolingHttpClientConnectionManager.java:125) at com.aliyun.oss.common.comm.DefaultServiceClient.createHttpClientConnectionManager(DefaultServiceClient.java:237) at com.aliyun.oss.common.comm.DefaultServiceClient.<init>(DefaultServiceClient.java:78) at com.aliyun.oss.OSSClient.<init>(OSSClient.java:268) at com.aliyun.oss.OSSClient.<init>(OSSClient.java:193) at OSSManagerImpl.upload(OSSManagerImpl.java:42) at OSSManagerImpl.main(OSSManagerImpl.java:63)このエラーは、OSS Java SDK V1 が Apache HttpClient 4.4.1 を使用しているのに対し、プロジェクトが競合するバージョンの Apache HttpClient または commons-httpclient JAR パッケージを使用しているために発生します。プロジェクトディレクトリで
mvn dependency:treeコマンドを実行して、プロジェクトが使用している JAR パッケージとそのバージョンを表示できます。プロジェクトは Apache HttpClient 4.3 を使用しており、これが標準バージョンと競合しています:[INFO] --- maven-dependency-plugin:2.2:tree (default-cli) @ maven-demo --- [INFO] com.aliyun.oss:maven-demo:jar:0.1.1-SNAPSHOT [INFO] +- junit:junit:jar:4.10:test [INFO] | \- org.hamcrest:hamcrest-core:jar:1.1:test [INFO] +- org.apache.httpcomponents:httpclient:jar:4.3:compile [INFO] | +- org.apache.httpcomponents:httpcore:jar:4.3:compile [INFO] | +- commons-logging:commons-logging:jar:1.1.3:compile [INFO] | \- commons-codec:commons-codec:jar:1.6:compile [INFO] \- com.aliyun.oss:aliyun-sdk-oss:jar:2.2.1:compile [INFO] +- org.jdom:jdom:jar:1.1:compile [INFO] \- net.sf.json-lib:json-lib:jar:jdk15:2.4:compile [INFO] +- commons-beanutils:commons-beanutils:jar:1.8.0:compile [INFO] +- commons-collections:commons-collections:jar:3.2.1:compile [INFO] +- commons-lang:commons-lang:jar:2.5:compile [INFO] \- net.sf.ezmorph:ezmorph:jar:1.0.6:compile -
ソリューション
次の 2 つの方法のいずれかでパッケージの競合を解決します:
-
バージョンの統一:プロジェクトが Apache HttpClient 4.4.1 と競合するバージョンを使用している場合は、プロジェクトをバージョン 4.4.1 を使用するように更新し、`pom.xml` ファイルから他のバージョンの Apache HttpClient への依存関係を削除します。プロジェクトが commons-httpclient を使用している場合も、競合が存在する可能性があります。commons-httpclient の依存関係を削除してください。
-
依存関係の競合の解決:プロジェクトが複数のサードパーティパッケージに依存しており、これらのパッケージが異なるバージョンの Apache HttpClient に依存している場合、プロジェクトで依存関係の競合が発生します。exclusion タグを使用して解決できます。詳細については、「Maven ガイド」をご参照ください。
OSS Java SDK V1 は、以下のパッケージバージョンに依存しています。競合解決方法は HttpClient と同様です。
[INFO] com.aliyun.oss:maven-demo:jar:0.1.1-SNAPSHOT [INFO] +- junit:junit:jar:4.10:test [INFO] | \- org.hamcrest:hamcrest-core:jar:1.1:test [INFO] \- com.aliyun.oss:aliyun-sdk-oss:jar:2.2.1:compile [INFO] +- org.apache.httpcomponents:httpclient:jar:4.4.1:compile [INFO] | +- org.apache.httpcomponents:httpcore:jar:4.4.1:compile [INFO] | +- commons-logging:commons-logging:jar:1.2:compile [INFO] | \- commons-codec:commons-codec:jar:1.9:compile [INFO] +- org.jdom:jdom:jar:1.1:compile [INFO] \- net.sf.json-lib:json-lib:jar:jdk15:2.4:compile [INFO] +- commons-beanutils:commons-beanutils:jar:1.8.0:compile [INFO] +- commons-collections:commons-collections:jar:3.2.1:compile [INFO] +- commons-lang:commons-lang:jar:2.5:compile [INFO] \- net.sf.ezmorph:ezmorph:jar:1.0.6:compile -
パッケージの欠落
-
原因
OSS Java SDK V1 を使用しているときに、以下のようなエラーが発生した場合、プロジェクトに OSS Java SDK V1 のコンパイルまたは実行に必要なパッケージが欠落している可能性があります。
Exception in thread "main" java.lang.NoClassDefFoundError: org/apache/http/auth/Credentials at com.aliyun.oss.OSSClient.<init>(OSSClient.java:268) at com.aliyun.oss.OSSClient.<init>(OSSClient.java:193) at com.aliyun.oss.demo.HelloOSS.main(HelloOSS.java:76) Caused by: java.lang.ClassNotFoundException: org.apache.http.auth.Credentials at java.net.URLClassLoader$1.run(URLClassLoader.java:366) at java.net.URLClassLoader$1.run(URLClassLoader.java:355) at java.security.AccessController.doPrivileged(Native Method) at java.net.URLClassLoader.findClass(URLClassLoader.java:354) at java.lang.ClassLoader.loadClass(ClassLoader.java:425) at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:308) at java.lang.ClassLoader.loadClass(ClassLoader.java:358) ... 3 moreまたは
Exception in thread "main" java.lang.NoClassDefFoundError: org/apache/http/protocol/HttpContext at com.aliyun.oss.OSSClient.<init>(OSSClient.java:268) at com.aliyun.oss.OSSClient.<init>(OSSClient.java:193) at com.aliyun.oss.demo.HelloOSS.main(HelloOSS.java:76) Caused by: java.lang.ClassNotFoundException: org.apache.http.protocol.HttpContext at java.net.URLClassLoader$1.run(URLClassLoader.java:366) at java.net.URLClassLoader$1.run(URLClassLoader.java:355) at java.security.AccessController.doPrivileged(Native Method) at java.net.URLClassLoader.findClass(URLClassLoader.java:354) at java.lang.ClassLoader.loadClass(ClassLoader.java:425) at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:308) at java.lang.ClassLoader.loadClass(ClassLoader.java:358) ... 3 moreまたは
Exception in thread "main" java.lang.NoClassDefFoundError: org/jdom/input/SAXBuilder at com.aliyun.oss.internal.ResponseParsers.getXmlRootElement(ResponseParsers.java:645) at … … at com.aliyun.oss.OSSClient.doesBucketExist(OSSClient.java:471) at com.aliyun.oss.OSSClient.doesBucketExist(OSSClient.java:465) at com.aliyun.oss.demo.HelloOSS.main(HelloOSS.java:82) Caused by: java.lang.ClassNotFoundException: org.jdom.input.SAXBuilder at java.net.URLClassLoader$1.run(URLClassLoader.java:366) at java.net.URLClassLoader$1.run(URLClassLoader.java:355) at java.security.AccessController.doPrivileged(Native Method) at java.net.URLClassLoader.findClass(URLClassLoader.java:354) at java.lang.ClassLoader.loadClass(ClassLoader.java:425) at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:308) at java.lang.ClassLoader.loadClass(ClassLoader.java:358) ... 11 moreOSS Java SDK V1 は以下のパッケージに依存しています:
-
aliyun-sdk-oss-2.2.1.jar
-
hamcrest-core-1.1.jar
-
jdom-1.1.jar
-
commons-codec-1.9.jar
-
httpclient-4.4.1.jar
-
commons-logging-1.2.jar
-
httpcore-4.4.1.jar
-
log4j-1.2.15.jar
これらのうち、log4j-1.2.15.jar はオプションの依存関係です。ロギング機能が必要な場合にのみこのパッケージを追加してください。他のパッケージは必須です。
-
-
ソリューション
OSS Java SDK V1 が依存するパッケージをプロジェクトに追加します。以下のいずれかの方法を使用できます:
-
Eclipse プロジェクト:「SDK のインストール」をご参照ください。
-
Ant プロジェクト:OSS Java SDK V1 が依存するパッケージをプロジェクトの lib ディレクトリに配置します。
-
直接コンパイル:
-classpathまたは-cpコマンドを使用して、OSS Java SDK V1 が依存するパッケージのパスを指定するか、これらのパッケージをクラスパスに配置します。
-
接続タイムアウト
-
原因
OSS Java SDK V1 プログラムを実行すると、エンドポイントが正しくないか、ネットワーク接続の問題により、以下のようなエラーが発生することがあります。
com.aliyun.oss.ClientException: SocketException at com.aliyun.oss.common.utils.ExceptionFactory.createNetworkException(ExceptionFactory.java:71) at com.aliyun.oss.common.comm.DefaultServiceClient.sendRequestCore(DefaultServiceClient.java:116) at com.aliyun.oss.common.comm.ServiceClient.sendRequestImpl(ServiceClient.java:121) at com.aliyun.oss.common.comm.ServiceClient.sendRequest(ServiceClient.java:67) at com.aliyun.oss.internal.OSSOperation.send(OSSOperation.java:92) at com.aliyun.oss.internal.OSSOperation.doOperation(OSSOperation.java:140) at com.aliyun.oss.internal.OSSOperation.doOperation(OSSOperation.java:111) at com.aliyun.oss.internal.OSSBucketOperation.getBucketInfo(OSSBucketOperation.java:1152) at com.aliyun.oss.OSSClient.getBucketInfo(OSSClient.java:1220) at com.aliyun.oss.OSSClient.getBucketInfo(OSSClient.java:1214) at com.aliyun.oss.demo.HelloOSS.main(HelloOSS.java:94) Caused by: org.apache.http.conn.HttpHostConnectException: Connect to oss-test.oss-cn-hangzhou-internal.aliyuncs.com:80 [oss-test.oss-cn-hangzhou-internal.aliyuncs.com/10.84.135.99] failed: Connection timed out: connect at org.apache.http.impl.conn.DefaultHttpClientConnectionOperator.connect(DefaultHttpClientConnectionOperator.java:151) at org.apache.http.impl.conn.PoolingHttpClientConnectionManager.connect(PoolingHttpClientConnectionManager.java:353) at org.apache.http.impl.execchain.MainClientExec.establishRoute(MainClientExec.java:380) at org.apache.http.impl.execchain.MainClientExec.execute(MainClientExec.java:236) at org.apache.http.impl.execchain.ProtocolExec.execute(ProtocolExec.java:184) at org.apache.http.impl.execchain.RedirectExec.execute(RedirectExec.java:110) at org.apache.http.impl.client.InternalHttpClient.doExecute(InternalHttpClient.java:184) at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:82) at com.aliyun.oss.common.comm.DefaultServiceClient.sendRequestCore(DefaultServiceClient.java:113) ... 9 more -
ソリューション
ossutil ツールを使用して、エラーの原因を迅速に特定し、問題を解決できます。
SignatureDoesNotMatch エラー
-
原因 1:AccessKey ペア情報の不一致
AccessKey ID と AccessKey Secret が一致しません。AccessKey ID と AccessKey Secret の取得方法については、「AccessKey ペアの作成」をご参照ください。
-
原因 2:署名付き URL の誤った使用
以下は、署名付き URL の誤った使用例です:
GeneratePresignedUrlRequest request = new GeneratePresignedUrlRequest(bucketName, object); request.setExpiration( new Date(new Date().getTime() + 3600 * 1000)); request.addUserMetadata("author"); URL url = ossClient.generatePresignedUrl(request); Map<String, String> header = new HashMap<String, String>(); header.put("author"); ossClient.putObject(url, new ByteArrayInputStream("Hello OSS".getBytes()), -1, header);Method パラメーターが指定されていない場合、デフォルトで GET メソッドが使用されます。しかし、上記の例は PutObject リクエストです。したがって、Method パラメーターを指定し、PUT に設定する必要があります。
PutObject リクエストを送信する際、リクエストヘッダーのカスタムメタデータには
x-oss-meta-のプレフィックスを付ける必要があります。上記の例では、カスタムメタデータをx-oss-meta-authorに変更する必要があります。ソリューション:Method パラメーターを指定し、ヘッダーのプレフィックスを変更します。
request.addUserMetadata("author"); request.setMethod(HttpMethod.PUT); URL url = ossClient.generatePresignedUrl(request); Map<String, String> header = new HashMap<String, String>(); header.put("x-oss-meta-" + "author"); ossClient.putObject(url, new ByteArrayInputStream("Hello OSS".getBytes()), -1, header); -
原因 3:HttpClient のバージョン互換性の問題
-
3.7.0 より前の OSS SDK バージョンが使用されており、プロジェクトに HttpClient 4.5.9 以降が導入されている。
-
アップロードされたファイル名に
+文字が含まれており、HttpClient 4.5.9 は+文字を URL エンコードしません。これにより、クライアントとサーバーで計算された署名が一致しなくなります。
320 POST /a HTTP/1.1 (application/json) 107 HTTP/1.1 200 (application/json) 453 PUT /%E4%B8%AD%E6%96%87%2B%E6%B5%8B%E8%AF%95 HTTP/1.1 375 HTTP/1.1 200 OK 364 POST /p HTTP/1.1 (application/json) 1108 HTTP/1.1 200 (application/json) 1017 POST /a HTTP/1.1 (application/json) 107 HTTP/1.1 200 (application/json) 450 PUT /%E4%B8%AD%E6%96%87+%E6%B5%8B%E8%AF%95 HTTP/1.1 1183 HTTP/1.1 403 Forbidden 325 POST /a HTTP/1.1 (application/json) 107 HTTP/1.1 200 (application/json)ソリューション:以下のいずれかの方法を使用します。
-
OSS SDK をバージョン 3.11.1 以降にアップグレードして、HttpClient 4.5.9 との互換性を確保します。
-
冗長な HttpClient の依存関係を削除します。OSS SDK を導入すると、HttpClient の依存関係が自動的に導入されます。サードパーティのライブラリも HttpClient を導入している場合は、「パッケージの競合」のソリューションをご参照ください。
-
-
原因 4:HttpClient の文字セット互換性の問題
HttpClient 4.5.10 は、ヘッダー内の ISO-8859-1 標準外の文字をサポートしていません。HttpClient 4.5.10 以降のバージョンを使用するプロジェクトでは、リクエストヘッダーに
x-oss-meta-で始まるカスタムメタデータ内の中国語文字など、ISO-8859-1 標準外の文字が含まれている場合に問題が発生します。String content = "123"; ObjectMetadata metadata = new ObjectMetadata(); metadata.setHeader("x-oss-meta-filename", "xxx"); PutObjectRequest request = new PutObjectRequest(bucketName, objectName, new ByteArrayInputStream(content.getBytes())); request.setMetadata(metadata); ossClient.putObject(request);ソリューション:以下のいずれかの方法を使用します。
-
「パッケージの競合」のソリューションを参照して、競合する HttpClient バージョンを削除します。
-
リクエストヘッダーには、ISO-8859-1 標準に準拠した文字のみを渡します。
-
「レスポンス結果の解析に失敗しました」例外
com.aliyun.oss.OSSException: Failed to parse the response result.
[ErrorCode]: InvalidResponse
[RequestId]: null
[HostId]: null
at com.aliyun.oss.common.utils.ExceptionFactory.createOSSException(ExceptionFactory.java:109)
at com.aliyun.oss.common.utils.ExceptionFactory.createInvalidResponseException(ExceptionFactory.java:91)
at com.aliyun.oss.common.utils.ExceptionFactory.createInvalidResponseException(ExceptionFactory.java:81)
at com.aliyun.oss.internal.OSSErrorResponseHandler.handle(OSSErrorResponseHandler.java:71)
at com.aliyun.oss.common.comm.ServiceClient.handleResponse(ServiceClient.java:248)
at com.aliyun.oss.common.comm.ServiceClient.sendRequestImpl(ServiceClient.java:130)
at com.aliyun.oss.common.comm.ServiceClient.sendRequest(ServiceClient.java:68)
at com.aliyun.oss.internal.OSSOperation.send(OSSOperation.java:94)
at com.aliyun.oss.internal.OSSOperation.doOperation(OSSOperation.java:149)
at com.aliyun.oss.internal.OSSOperation.doOperation(OSSOperation.java:113)
at com.aliyun.oss.internal.OSSObjectOperation.getObject(OSSObjectOperation.java:273)
at com.aliyun.oss.internal.OSSObjectOperation.getObject(OSSObjectOperation.java:301)
at com.aliyun.oss.OSSClient.getObject(OSSClient.java:545)
-
原因
クライアント側の特定の特殊なソフトウェアが HTTP リクエストを傍受しているか、パブリックネットワークルートが HTTP リクエストをハイジャックしています。
Java 9 以降で OSS Java SDK V1 を使用しており、pom.xml ファイルに JAXB 関連の依存関係を追加していません。
-
ソリューション
HTTPS リクエストに切り替えます。
JAXB 関連の依存関係を追加します。手順については、「SDK のインストール」をご参照ください。
org.apache.http.NoHttpResponseException: ターゲットサーバーが応答しませんでした
-
原因
OSS Java SDK V1 プログラムを実行すると、以下のようなエラーが報告されます:
com.aliyun.oss.ClientException: Unknown at com.aliyun.oss.common.utils.ExceptionFactory.createNetworkException(ExceptionFactory.java:68) ~[aliyun-sdk-oss-2.1.0.jar:na] at com.aliyun.oss.common.comm.DefaultServiceClient.sendRequestCore(DefaultServiceClient.java:115) ~[aliyun-sdk-oss-2.1.0.jar:na] at com.aliyun.oss.common.comm.ServiceClient.sendRequestImpl(ServiceClient.java:121) ~[aliyun-sdk-oss-2.1.0.jar:na] at com.aliyun.oss.common.comm.ServiceClient.sendRequest(ServiceClient.java:67) ~[aliyun-sdk-oss-2.1.0.jar:na] at com.aliyun.oss.internal.OSSOperation.send(OSSOperation.java:92) ~[aliyun-sdk-oss-2.1.0.jar:na] at com.aliyun.oss.internal.OSSOperation.doOperation(OSSOperation.java:140) ~[aliyun-sdk-oss-2.1.0.jar:na] at com.aliyun.oss.internal.OSSOperation.doOperation(OSSOperation.java:111) ~[aliyun-sdk-oss-2.1.0.jar:na] at com.aliyun.oss.internal.OSSMultipartOperation.initiateMultipartUpload(OSSMultipartOperation.java:206) ~[aliyun-sdk-oss-2.1.0.jar:na] at com.aliyun.oss.OSSClient.initiateMultipartUpload(OSSClient.java:765) ~[aliyun-sdk-oss-2.1.0.jar:na] at com.taobao.agoo.dump.client.OssTools.multipartUpload(OssTools.java:79) ~[agoo-dump-client-2.0.0-SNAPSHOT.jar:na] at com.taobao.agoo.dump.biz.manager.TaskExecutorManager$UploadTask.run(TaskExecutorManager.java:114) ~[agoo-dump-biz-2.0.0-SNAPSHOT.jar:na] at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:471) [na:1.7.0_51] at java.util.concurrent.FutureTask.run(FutureTask.java:262) [na:1.7.0_51] at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145) [na:1.7.0_51] at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615) [na:1.7.0_51] at java.lang.Thread.run(Thread.java:744) [na:1.7.0_51] Caused by: org.apache.http.NoHttpResponseException: The target server failed to respond at org.apache.http.impl.conn.DefaultHttpResponseParser.parseHead(DefaultHttpResponseParser.java:143) ~[httpclient-4.4.jar:4.4] at org.apache.http.impl.conn.DefaultHttpResponseParser.parseHead(DefaultHttpResponseParser.java:57) ~[httpclient-4.4.jar:4.4] at org.apache.http.impl.io.AbstractMessageParser.parse(AbstractMessageParser.java:261) ~[httpcore-4.4.jar:4.4] at org.apache.http.impl.DefaultBHttpClientConnection.receiveResponseHeader(DefaultBHttpClientConnection.java:165) ~[httpcore-4.4.jar:4.4] at org.apache.http.impl.conn.CPoolProxy.receiveResponseHeader(CPoolProxy.java:167) ~[httpclient-4.4.jar:4.4] at org.apache.http.protocol.HttpRequestExecutor.doReceiveResponse(HttpRequestExecutor.java:272) ~[httpcore-4.4.jar:4.4]期限切れの接続を使用すると、上記のエラーが発生します。このエラーは、Java SDK バージョン 2.1.2 より前でのみ発生します。
-
ソリューション
OSS Java SDK V1 をバージョン 2.1.2 以降にアップグレードします。
JVM 内に多数の org.apache.http.impl.conn.PoolingHttpClientConnectionManager インスタンスが存在する
-
原因
ossClient が正しく閉じられていませんでした。
-
ソリューション
ossClient の実行が終了したら閉じるか、シングルトンパターンを使用します。
OSS Java SDK V1 の呼び出しが応答しない
-
原因
OSS Java SDK V1 の呼び出しが応答しません。
jstack -l pidコマンドを実行してスタックを表示すると、以下の位置で問題を特定できます:"main" prio=6 tid=0x000000000291e000 nid=0xc40 waiting on condition [0x0000000002dae000] java.lang.Thread.State: WAITING (parking) at sun.misc.Unsafe.park(Native Method) - parking to wait for <0x00000007d85697f8> (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject) at java.util.concurrent.locks.LockSupport.park(LockSupport.java:186) at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSynchronizer.java:2043) at org.apache.http.pool.PoolEntryFuture.await(PoolEntryFuture.java:138) at org.apache.http.pool.AbstractConnPool.getPoolEntryBlocking(AbstractConnPool.java:306) at org.apache.http.pool.AbstractConnPool.access$000(AbstractConnPool.java:64) at org.apache.http.pool.AbstractConnPool$2.getPoolEntry(AbstractConnPool.java:192) at org.apache.http.pool.AbstractConnPool$2.getPoolEntry(AbstractConnPool.java:185) at org.apache.http.pool.PoolEntryFuture.get(PoolEntryFuture.java:107) at org.apache.http.impl.conn.PoolingHttpClientConnectionManager.leaseConnection(PoolingHttpClientConnectionManager.java:276) at org.apache.http.impl.conn.PoolingHttpClientConnectionManager$1.get(PoolingHttpClientConnectionManager.java:263) at org.apache.http.impl.execchain.MainClientExec.execute(MainClientExec.java:190) at org.apache.http.impl.execchain.ProtocolExec.execute(ProtocolExec.java:184) at org.apache.http.impl.execchain.RedirectExec.execute(RedirectExec.java:110) at org.apache.http.impl.client.InternalHttpClient.doExecute(InternalHttpClient.java:184) at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:82) at com.aliyun.oss.common.comm.DefaultServiceClient.sendRequestCore(DefaultServiceClient.java:113) at com.aliyun.oss.common.comm.ServiceClient.sendRequestImpl(ServiceClient.java:123) at com.aliyun.oss.common.comm.ServiceClient.sendRequest(ServiceClient.java:68) at com.aliyun.oss.internal.OSSOperation.send(OSSOperation.java:94) at com.aliyun.oss.internal.OSSOperation.doOperation(OSSOperation.java:146) at com.aliyun.oss.internal.OSSOperation.doOperation(OSSOperation.java:113) at com.aliyun.oss.internal.OSSObjectOperation.getObject(OSSObjectOperation.java:229) at com.aliyun.oss.OSSClient.getObject(OSSClient.java:629) at com.aliyun.oss.OSSClient.getObject(OSSClient.java:617) at samples.HelloOSS.main(HelloOSS.java:49)原因は、接続プール内の接続リークであり、使用後に ossObject が正しく閉じられていない可能性があります。
-
ソリューション
プログラムをチェックして、接続リークがないことを確認します。以下の方法で接続を正しく閉じます:
// ファイルを読み取ります。 OSSObject ossObject = ossClient.getObject(bucketName, objectName); // OSS 操作 // ossObject を閉じます。 ossObject.close();詳細なトラブルシューティング手順については、「応答しない OSS Java SDK V1 のトラブルシューティング」をご参照ください。
接続が閉じられました
-
原因
ossClient.getObject を使用しているときに、以下のようなエラーが発生した場合:
Exception in thread "main" org.apache.http.ConnectionClosedException: Premature end of Content-Length delimited message body (expected: 11990526; received: 202880) at org.apache.http.impl.io.ContentLengthInputStream.read(ContentLengthInputStream.java:180) at org.apache.http.impl.io.ContentLengthInputStream.read(ContentLengthInputStream.java:200) at org.apache.http.impl.io.ContentLengthInputStream.close(ContentLengthInputStream.java:103) at org.apache.http.impl.execchain.ResponseEntityProxy.streamClosed(ResponseEntityProxy.java:128) at org.apache.http.conn.EofSensorInputStream.checkClose(EofSensorInputStream.java:228) at org.apache.http.conn.EofSensorInputStream.close(EofSensorInputStream.java:174) at java.io.FilterInputStream.close(FilterInputStream.java:181) at java.io.FilterInputStream.close(FilterInputStream.java:181) at com.aliyun.oss.event.ProgressInputStream.close(ProgressInputStream.java:147) at java.io.FilterInputStream.close(FilterInputStream.java:181) at samples.HelloOSS.main(HelloOSS.java:39)原因は、2 回のデータ読み取りの間隔が 1 分を超えていることです。OSS は 1 分以上アイドル状態の接続を閉じます。
-
ソリューション
毎回一部のデータのみを読み取り、処理時間が異なる場合は、範囲ダウンロードを使用して接続の切断を回避します。範囲ダウンロードが完了すると、接続は自動的に閉じます。範囲ダウンロード (OSS Java SDK V1)。
メモリリーク
-
原因
OSS Java SDK V1 を呼び出すプログラムは、一定期間 (ビジネス量に応じて数時間から数日) 実行するとメモリリークが発生します。Eclipse Memory Analyzer (MAT) を使用してメモリ使用量を分析することをお勧めします。詳細については、「MAT でヒープダンプファイルを分析する」をご参照ください。
分析結果が下の図のようになっている場合 (PoolingHttpClientConnectionManager がメモリの 96% を占めている)、原因はプログラムで
new OSSClientが複数回実行されたにもかかわらず、ossClient.shutdownが呼び出されなかったため、メモリリークが発生した可能性があります。
-
ソリューション
new OSSClient操作が完了したら、shutdownメソッドを呼び出して閉じます。new OSSClientとossClient.shutdownがペアで使用されていることを確認してください。
ossClient.shutdown 呼び出し時に InterruptedException が報告される
-
原因
2.3.0 より前のバージョンの OSS Java SDK V1 は、
ossClient.shutdownを呼び出すと、以下の例外を報告します:java.lang.InterruptedException: sleep interrupted at java.lang.Thread.sleep(Native Method) at com.aliyun.oss.common.comm.IdleConnectionReaper.run(IdleConnectionReaper:76)原因は、ossClient のバックエンドスレッド IdleConnectionReaper が定期的にアイドル接続を閉じるためです。IdleConnectionReaper が Sleep 中に ossClient.shutdown が呼び出されると、上記のエラーが報告されます。
-
ソリューション
以下のコードを使用して例外を無視します:
try { ossClient.shutdown(); } catch(Exception e) { }
「SDK.ServerUnreachable : Speicified endpoint or uri is not valid」例外
SunshineE/android/01040181-2018-05-07173747-860769-online=1.jpg</cloudUrl><fileSize>4096</fileSize><lossName/><loss
...skipping...
com.aliyuncs.exceptions.ClientException: SDK.ServerUnreachable : Speicified endpoint or uri is not valid.
at com.aliyuncs.DefaultAcsClient.doAction(DefaultAcsClient.java:201)
at com.aliyuncs.DefaultAcsClient.doAction(DefaultAcsClient.java:151)
at com.aliyuncs.DefaultAcsClient.doAction(DefaultAcsClient.java:59)
at com.aliyuncs.DefaultAcsClient.getAcsResponse(DefaultAcsClient.java:103)
at com.sunyard.insurance.oss.aliyun.GetSts.assumeRole(GetSts.java:50)
at com.sunyard.insurance.oss.aliyun.GetSts.getSts(GetSts.java:60)
at com.sunyard.insurance.ecm.web.action.oss.OssInfoAction.getUpOssInfo(OssInfoAction.java:259)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
-
原因
-
クライアントが STS に同時に多数のリクエストを送信している。
-
サーバーへのネットワーク接続がタイムアウトしている。
-
使用している STS SDK と SDK コアが最新バージョンではない。
-
-
ソリューション
-
OSS の同時実行数を減らします。クライアントが STS に同時に多数のリクエストを送信している場合、クライアントの ECS インスタンスまたはローカルコンピュータが負荷を処理できない可能性があります。
-
ユーザーからサーバーへのネットワーク接続がタイムアウトしています。パケットをキャプチャしてこれを確認できます。
-
STS SDK と SDK コアを最新バージョンにアップグレードします。
-
NoSuchKey
case:java.lang.Exception: com.aliyun.oss.OSSException:
Not Foundn[ErrorCode]: NoSuchKeyn
-
原因
ソースファイルが存在しません。
-
ソリューション
SocketException
2018-10-10 16:21:11,127 ERROR com.qunhe.instdeco.plan.maxservice.convert.Converter
downloadOssObject:taskId:LO63HXQKN4BMWM4BAU888888:
com.aliyun.oss.ClientException: SocketException
at com.aliyun.oss.common.utils.ExceptionFactory.createNetworkException(ExceptionFactory.java:71)
at com.aliyun.oss.common.comm.DefaultServiceClient.sendRequestCore(DefaultServiceClient.java:128)
at com.aliyun.oss.common.comm.ServiceClient.sendRequestImpl(ServiceClient.java:123)
at com.aliyun.oss.common.comm.ServiceClient.sendRequest(ServiceClient.java:68)
at com.aliyun.oss.internal.OSSOperation.send(OSSOperation.java:94)
at com.aliyun.oss.internal.OSSOperation.doOperation(OSSOperation.java:149)
at com.aliyun.oss.internal.OSSOperation.doOperation(OSSOperation.java:113)
at com.aliyun.oss.internal.OSSObjectOperation.getObject(OSSObjectOperation.java:273)
-
原因
ソケットが初期化フェーズで失敗し、リクエストが OSS に到達する前に失敗した可能性があります。
-
ソリューション
以下の点を確認することをお勧めします:
-
問題が発生したときにネットワークジッターが発生したかどうか。
-
ホストのソケット接続数が上限に達しているかどうか。
-
問題が発生したときに接続数が SDK の maxconnection 設定を超えていたかどうかを確認します。接続数が maxconnection 設定を超えると、ソケット例外も発生します。
上記に問題がない場合は、tcpdump または Wireshark をデプロイしてパケットをキャプチャし、問題が再発した後にデータパケットを分析することをお勧めします。
-
OSS PostObject のコールバックがトリガーされない
OSS PostObject のコールバックがトリガーされませんが、同じコールバックが PutObject によってトリガーされます。通常、JSON 形式が正しくないか、コールバックが失敗した場合、対応するメッセージが返されます。この場合、Put と Post のコールバックの動作を個別にテストする必要があります:
以下の Wireshark キャプチャは、OSS コールバック HTTP POST リクエストとサーバーの応答を示しています:
POST /RevIce.ashx HTTP/1.1
Host: 47.xx.xxx.168
Connection: close
Content-Length: xxx
Authorization: xxx
Content-MD5: KdeBTxxx
Content-Type: appli...
User-Agent: aliyun-xxx
x-oss-additional-he...
x-oss-bucket: null8
x-owner: A4A64...
x-oss-pub-key-url: xxx
x-oss-request-id: xxx
x-oss-signature-ver...
x-oss-tag: CALLBACK
eagleye-rpcid: 0.1
bucket: xxx
HTTP/1.1 200 OK
Cache-Control: private
Transfer-Encoding: chunked
Content-Type: text/plain
Server: Microsoft-IIS/7.5
X-AspNet-Version: 4.0.30319
X-Powered-By: ASP.NET
Date: Mon, 12 Feb 2018 02:52:44 GMT
Connection: close
{"a":"b"}
-
原因
リクエストを送信する際、`callback` パラメーターが `file` パラメーター内に誤って配置されています。
LTAI*xxx --94311149156168 Content-Disposition: form-data; name="policy" eyjleHBpcmF0aW9UIjogIjIxMjAtMDEtMDFU --94311149156168 Content-Disposition: form-data; name="Signature" gncf07Apde0vqaMWBto18XxzoH0= --94311149156168 Content-Disposition: form-data; name="file"; filename="1.txt" Content-Type: text/plain --94311149156168 Content-Disposition: form-data; name="callback" eyJ3YWxsYmFja1VybCI6Imh0dHA6Ly9vc3MtZGVtby5hbGl5dW5jcy5jb20eyJ3YWxsYmFja1VybCI6ImhxMTYxMTYxNjE2MTYxNjE2 12345678910 --94311149156168-- HTTP/1.1 204 No Content Server: AliyunOSS Date: xxx -
ソリューション
callback と file パラメーターの位置を調整します。
Content-Disposition: form-data; name="policy" eyjleHBpcmF0aW9uIjogIjIxMjAtMDEtMDFUMTI6MDA6MDAuMDAwWiIs]xxx --9431149156168 Content-Disposition: form-data; name="Signature" gncf07Apde0vqaMWBtol8XxzoH0= --9431149156168 Content-Disposition: form-data; name="callback" eyJjYWxsYmFja1VybCI6Imh0dHA6Ly80xxx MTYuMTY4LjFxxxIn0= --9431149156168 Content-Disposition: form-data; name="file"; filename="1.txt" Content-Type: text/plain 12345678910 --9431149156168-- HTTP/1.1 200 OK Server: AliyunOSS Date: Mon, 12 Feb 2018 06:39:22 GMT Content-Type: application/jsonこの時点で、テスト結果はビジネスサーバーがリクエストを正常にキャプチャしたことを示しています。
POST /Revice.ashx HTTP/1.1 Host: 47.93.116.168 Connection: close Content-Length: 26 Authorization: kn8kVDJOdte9CHcRX1=xxx Content-Type: application/x-www-xxx Date: Mon, 12 Feb 2018 06:40:54 User-Agent: aliyun-oss-callback x-oss-additional-headers: x-oss-bucket: ruide x-oss-owner: 44414 x-oss-pub-key-url: aHR0cHM6Ly9nb2xxx...SuZN= x-oss-request-id: 5A8136F6002618Hxxx x-oss-requester: 232379785371xxx x-oss-signature-version: 1.0 x-oss-tag: CALLBACK eagleeye-rpcid: 0.1 {"bucket"=ruide,"size"=11} HTTP/1.1 200 OK Cache-Control: private Transfer-Encoding: chunked Content-Type: text/plain Server: Microsoft-IIS/7.5 X-AspNet-Version: 4.0.30319 X-Powered-By: ASP.NET Date: Mon, 12 Feb 2018 06:40:54 GMT Connection: close {"a":"b"}
接続プールがシャットダウンされました
Caused by: java.lang.IllegalStateException: Connection pool shut down
at org.apache.http.util.Asserts.check(Asserts.java:34)
at org.apache.http.pool.AbstractConnPool.lease(AbstractConnPool.java:184)
at org.apache.http.impl.conn.PoolingHttpClientConnectionManager.requestConnection(PoolingHttpClientConnectionManager.java:251)
at org.apache.http.impl.execchain.MainClientExec.execute(MainClientExec.java:175)
at org.apache.http.impl.execchain.ProtocolExec.execute(ProtocolExec.java:184)
at org.apache.http.impl.execchain.RedirectExec.execute(RedirectExec.java:110)
at org.apache.http.impl.client.InternalHttpClient.doExecute(InternalHttpClient.java:184)
at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:82)
at com.aliyun.oss.common.comm.DefaultServiceClient.sendRequestCore(DefaultServiceClient.java:124)
at com.aliyun.oss.common.comm.ServiceClient.sendRequestImpl(ServiceClient.java:133)
... 8 more
-
原因
ossClient.shutdown()メソッドを呼び出した後も、ossClient を介してリクエストを送信し続けています。 -
ソリューション
呼び出しロジックを確認し、
ossClient.shutdown()メソッドを呼び出した後は、ossClient を介してリクエストを送信しないようにしてください。
Java SDK の generatePresignedUrl で生成されたリクエストで「リクエストの有効期限が切れています」エラーが発生する
-
原因
整数オーバーフローが、2038年問題に関連するタイムスタンプの問題を引き起こします。
URL に設定された有効期限後にアップロードリクエストが開始されます。
-
ソリューション
整数オーバーフローの場合は、Java SDK の有効期間が 2038 年を超えないようにすることをお勧めします。
URL に設定された有効期限後にアップロードリクエストが開始される場合は、有効期限がリクエストを開始する時刻より後になるように、合理的な有効期限を設定してください。
「無効なレスポンス」または「JAXB-API の実装がモジュールパスまたはクラスパスに見つかりません」エラー
-
原因
Java 9 以降を使用しており、JAXB 依存関係を追加していません。
-
ソリューション
JAXB 依存関係の追加方法については、「SDK のインストール」をご参照ください。
OSS Java SDK V1 の OSSClient はスレッドセーフですか?
-
OSSClient はスレッドセーフであり、複数のスレッドが同じインスタンスにアクセスできます。ビジネスニーズに応じて、単一の OSSClient インスタンスを再利用するか、複数のインスタンスを作成することができます。
-
OSSClient インスタンスは内部で接続プールを維持します。OSSClient インスタンスが不要になった場合は、shutdown メソッドを呼び出して閉じる必要があり、多数の OSSClient インスタンスを作成することによるリソース枯渇を避ける必要があります。
「AccessDenied Hierarchical namespace is disabled」エラーが報告される
-
原因
CreateDirectory、Rename、または DeleteDirectory API 操作を呼び出す前に、階層型名前空間が有効になっていませんでした。
-
ソリューション
バケットを作成する際に階層型名前空間を有効にします。具体的な手順については、「バケットの作成」をご参照ください。
クライアントネットワークは正常ですが、HTTP アクセス中に「接続リセット」エラーが報告されます。どうすればよいですか?
一部の地域の通信事業者が OSS ドメイン名をハイジャックする可能性があります。エンドポイントを介して HTTPS を設定します。「クライアントの設定」をご参照ください。
Java 17 で "com.sun.xml.bind.v2.runtime.reflect.opt.Injector.defineClass" が null のため "java.lang.reflect.Method.invoke(Object, Object[])" を呼び出せない
-
原因
JAXB は Java 9 で非推奨とマークされ、Java 11 で削除されました。
-
ソリューション
以下の依存関係を追加します:
<dependency> <groupId>com.sun.xml.bind</groupId> <artifactId>jaxb-impl</artifactId> <version>2.3.1</version> </dependency> <dependency> <groupId>com.sun.xml.messaging.saaj</groupId> <artifactId>saaj-impl</artifactId> <version>1.5.1</version> </dependency>
Java SDK の内部ログ出力を設定するにはどうすればよいですか?
Java SDK は、ログ出力に Apache Commons Logging (JCL) フレームワークを使用します。JCL は複数のロギング実装フレームワークを使用できます。詳細については、「JCL-Configuration」をご参照ください。最も一般的なものは、JCL over log4j または JCL over SLF4j です。実装方法は次のとおりです:
-
JCL over log4j:log4j 依存関係 (log4j 2.x には複数の実装フレームワークがあり、デフォルトは log4j-api+log4j-core) を導入し、log4j の設定方法に従って設定する必要があります。具体的な手順については、「APACHE LOG4J-API Separation」をご参照ください。
-
JCL over slf4j:jcl-over-slf4j と slf4j の依存関係 (slf4j にも slf4j-api+logback-classic など、複数の実装フレームワークがあります) を導入し、slf4j の設定方法に従って設定する必要があります。具体的な手順については、「SJF4J-Bridging legacy APIs」をご参照ください。
Apache Log4j は、OFF、FATAL、ERROR、WARN、INFO、DEBUG、TRACE、ALL など、さまざまなレベルのログを定義します。
log4j プロパティを設定することで、SDK ログを有効または無効にできます:
#
log4j.appender.DRFA=org.apache.log4j.DailyRollingFileAppender
log4j.appender.DRFA.File=${ossdemo.log.dir}/${ossdemo.log.file}
# 真夜中にロールオーバー
log4j.appender.DRFA.DatePattern=.yyyy-MM-dd
# 30 日間のバックアップ
#log4j.appender.DRFA.MaxBackupIndex=30
log4j.appender.DRFA.layout=org.apache.log4j.PatternLayout
# パターン形式:日付 ログレベル ロガー名 ログメッセージ
log4j.appender.DRFA.layout.ConversionPattern=%d{ISO8601} %p %c: %m%n
# デバッグパターン形式
#log4j.appender.DRFA.layout.ConversionPattern=%d{ISO8601} %-5p %c{2} (%F:%M(%L)) - %m%n
#
# コンソール
# これを使用したい場合は、上記の rootlogger に "console" を追加します
#
log4j.appender.console=org.apache.log4j.ConsoleAppender
log4j.appender.console.target=System.err
log4j.appender.console.layout=org.apache.log4j.PatternLayout
log4j.appender.console.layout.ConversionPattern=%d{yy/MM/dd HH:mm:ss} %p %c{2}: %m%n
log4j.logger.org.apache.http=off
# oss ログレベル
log4j.logger.com.aliyun.oss=DEBUG
OSS Java SDK V2 へのアップグレード
OSS Java SDK V2 が利用可能になりました。簡素化された API と改善されたリトライメカニズムを提供します。V1 から V2 に移行するには、「Java SDK V1 から V2 への移行ガイド」をご参照ください。