I am trying to use aws Transcribe to convert a wav file to text. I have uploaded a wav file to S3, which is located here and it has public read/write permissions: https://s3.us-east-1.amazonaws.com/csld8xmsdksdf8s9sk3mmdjsdifkjksdijsldk/Transcribe2.wav. The wav file is valid. I can download it in my browser and replay it (and it sounds like the origin recording), so I think we can rule out an invalid input file, file permissions, etc.
I am using java version: 1.8.0_275 for mac.
I expect my program to give me back the transcribed text: "Hello amazon Subscribe, what is this?"
Here is the actual program output, including exception:
/Library/Java/JavaVirtualMachines/adoptopenjdk-8.jdk/Contents/Home/bin/java "-javaagent:/Applications/IntelliJ IDEA CE.app/Contents/lib/idea_rt.jar=60898:/Applications/IntelliJ IDEA CE.app/Contents/bin" -Dfile.encoding=UTF-8 -classpath /Library/Java/JavaVirtualMachines/adoptopenjdk-8.jdk/Contents/Home/jre/lib/charsets.jar:/Library/Java/JavaVirtualMachines/adoptopenjdk-8.jdk/Contents/Home/jre/lib/ext/cldrdata.jar:/Library/Java/JavaVirtualMachines/adoptopenjdk-8.jdk/Contents/Home/jre/lib/ext/dnsns.jar:/Library/Java/JavaVirtualMachines/adoptopenjdk-8.jdk/Contents/Home/jre/lib/ext/jaccess.jar:/Library/Java/JavaVirtualMachines/adoptopenjdk-8.jdk/Contents/Home/jre/lib/ext/localedata.jar:/Library/Java/JavaVirtualMachines/adoptopenjdk-8.jdk/Contents/Home/jre/lib/ext/nashorn.jar:/Library/Java/JavaVirtualMachines/adoptopenjdk-8.jdk/Contents/Home/jre/lib/ext/sunec.jar:/Library/Java/JavaVirtualMachines/adoptopenjdk-8.jdk/Contents/Home/jre/lib/ext/sunjce_provider.jar:/Library/Java/JavaVirtualMachines/adoptopenjdk-8.jdk/Contents/Home/jre/lib/ext/sunpkcs11.jar:/Library/Java/JavaVirtualMachines/adoptopenjdk-8.jdk/Contents/Home/jre/lib/ext/zipfs.jar:/Library/Java/JavaVirtualMachines/adoptopenjdk-8.jdk/Contents/Home/jre/lib/jce.jar:/Library/Java/JavaVirtualMachines/adoptopenjdk-8.jdk/Contents/Home/jre/lib/jfr.jar:/Library/Java/JavaVirtualMachines/adoptopenjdk-8.jdk/Contents/Home/jre/lib/jsse.jar:/Library/Java/JavaVirtualMachines/adoptopenjdk-8.jdk/Contents/Home/jre/lib/management-agent.jar:/Library/Java/JavaVirtualMachines/adoptopenjdk-8.jdk/Contents/Home/jre/lib/resources.jar:/Library/Java/JavaVirtualMachines/adoptopenjdk-8.jdk/Contents/Home/jre/lib/rt.jar:/Library/Java/JavaVirtualMachines/adoptopenjdk-8.jdk/Contents/Home/lib/dt.jar:/Library/Java/JavaVirtualMachines/adoptopenjdk-8.jdk/Contents/Home/lib/jconsole.jar:/Library/Java/JavaVirtualMachines/adoptopenjdk-8.jdk/Contents/Home/lib/sa-jdi.jar:/Library/Java/JavaVirtualMachines/adoptopenjdk-8.jdk/Contents/Home/lib/tools.jar:/Users/cdornin/work/transcribe/target/classes:/Users/cdornin/.m2/repository/org/apiguardian/apiguardian-api/1.0.0/apiguardian-api-1.0.0.jar:/Users/cdornin/.m2/repository/org/junit/platform/junit-platform-commons/1.4.0/junit-platform-commons-1.4.0.jar:/Users/cdornin/.m2/repository/org/slf4j/slf4j-log4j12/1.7.25/slf4j-log4j12-1.7.25.jar:/Users/cdornin/.m2/repository/org/slf4j/slf4j-api/1.7.25/slf4j-api-1.7.25.jar:/Users/cdornin/.m2/repository/log4j/log4j/1.2.17/log4j-1.2.17.jar:/Users/cdornin/.m2/repository/software/amazon/awssdk/transcribe/2.15.65/transcribe-2.15.65.jar:/Users/cdornin/.m2/repository/software/amazon/awssdk/protocol-core/2.15.65/protocol-core-2.15.65.jar:/Users/cdornin/.m2/repository/software/amazon/awssdk/aws-json-protocol/2.15.65/aws-json-protocol-2.15.65.jar:/Users/cdornin/.m2/repository/software/amazon/awssdk/sdk-core/2.15.65/sdk-core-2.15.65.jar:/Users/cdornin/.m2/repository/software/amazon/awssdk/profiles/2.15.65/profiles-2.15.65.jar:/Users/cdornin/.m2/repository/org/reactivestreams/reactive-streams/1.0.2/reactive-streams-1.0.2.jar:/Users/cdornin/.m2/repository/software/amazon/awssdk/auth/2.15.65/auth-2.15.65.jar:/Users/cdornin/.m2/repository/software/amazon/eventstream/eventstream/1.0.1/eventstream-1.0.1.jar:/Users/cdornin/.m2/repository/software/amazon/awssdk/http-client-spi/2.15.65/http-client-spi-2.15.65.jar:/Users/cdornin/.m2/repository/software/amazon/awssdk/regions/2.15.65/regions-2.15.65.jar:/Users/cdornin/.m2/repository/software/amazon/awssdk/annotations/2.15.65/annotations-2.15.65.jar:/Users/cdornin/.m2/repository/software/amazon/awssdk/utils/2.15.65/utils-2.15.65.jar:/Users/cdornin/.m2/repository/software/amazon/awssdk/aws-core/2.15.65/aws-core-2.15.65.jar:/Users/cdornin/.m2/repository/software/amazon/awssdk/metrics-spi/2.15.65/metrics-spi-2.15.65.jar:/Users/cdornin/.m2/repository/software/amazon/awssdk/apache-client/2.15.65/apache-client-2.15.65.jar:/Users/cdornin/.m2/repository/org/apache/httpcomponents/httpclient/4.5.13/httpclient-4.5.13.jar:/Users/cdornin/.m2/repository/commons-codec/commons-codec/1.11/commons-codec-1.11.jar:/Users/cdornin/.m2/repository/org/apache/httpcomponents/httpcore/4.4.11/httpcore-4.4.11.jar:/Users/cdornin/.m2/repository/software/amazon/awssdk/netty-nio-client/2.15.65/netty-nio-client-2.15.65.jar:/Users/cdornin/.m2/repository/io/netty/netty-codec-http/4.1.53.Final/netty-codec-http-4.1.53.Final.jar:/Users/cdornin/.m2/repository/io/netty/netty-codec-http2/4.1.53.Final/netty-codec-http2-4.1.53.Final.jar:/Users/cdornin/.m2/repository/io/netty/netty-codec/4.1.53.Final/netty-codec-4.1.53.Final.jar:/Users/cdornin/.m2/repository/io/netty/netty-transport/4.1.53.Final/netty-transport-4.1.53.Final.jar:/Users/cdornin/.m2/repository/io/netty/netty-resolver/4.1.53.Final/netty-resolver-4.1.53.Final.jar:/Users/cdornin/.m2/repository/io/netty/netty-common/4.1.53.Final/netty-common-4.1.53.Final.jar:/Users/cdornin/.m2/repository/io/netty/netty-buffer/4.1.53.Final/netty-buffer-4.1.53.Final.jar:/Users/cdornin/.m2/repository/io/netty/netty-handler/4.1.53.Final/netty-handler-4.1.53.Final.jar:/Users/cdornin/.m2/repository/io/netty/netty-transport-native-epoll/4.1.53.Final/netty-transport-native-epoll-4.1.53.Final-linux-x86_64.jar:/Users/cdornin/.m2/repository/io/netty/netty-transport-native-unix-common/4.1.53.Final/netty-transport-native-unix-common-4.1.53.Final.jar:/Users/cdornin/.m2/repository/com/typesafe/netty/netty-reactive-streams-http/2.0.4/netty-reactive-streams-http-2.0.4.jar:/Users/cdornin/.m2/repository/com/typesafe/netty/netty-reactive-streams/2.0.4/netty-reactive-streams-2.0.4.jar:/Users/cdornin/.m2/repository/software/amazon/awssdk/transcribestreaming/2.15.65/transcribestreaming-2.15.65.jar:/Users/cdornin/.m2/repository/com/amazonaws/aws-java-sdk-s3/1.11.939/aws-java-sdk-s3-1.11.939.jar:/Users/cdornin/.m2/repository/com/amazonaws/aws-java-sdk-kms/1.11.939/aws-java-sdk-kms-1.11.939.jar:/Users/cdornin/.m2/repository/com/amazonaws/aws-java-sdk-core/1.11.939/aws-java-sdk-core-1.11.939.jar:/Users/cdornin/.m2/repository/commons-logging/commons-logging/1.1.3/commons-logging-1.1.3.jar:/Users/cdornin/.m2/repository/software/amazon/ion/ion-java/1.0.2/ion-java-1.0.2.jar:/Users/cdornin/.m2/repository/com/fasterxml/jackson/dataformat/jackson-dataformat-cbor/2.6.7/jackson-dataformat-cbor-2.6.7.jar:/Users/cdornin/.m2/repository/joda-time/joda-time/2.8.1/joda-time-2.8.1.jar:/Users/cdornin/.m2/repository/com/amazonaws/jmespath-java/1.11.939/jmespath-java-1.11.939.jar:/Users/cdornin/.m2/repository/com/amazonaws/aws-java-sdk-transcribe/1.11.939/aws-java-sdk-transcribe-1.11.939.jar:/Users/cdornin/.m2/repository/io/minio/minio/8.0.3/minio-8.0.3.jar:/Users/cdornin/.m2/repository/com/carrotsearch/thirdparty/simple-xml-safe/2.7.1/simple-xml-safe-2.7.1.jar:/Users/cdornin/.m2/repository/com/google/guava/guava/29.0-jre/guava-29.0-jre.jar:/Users/cdornin/.m2/repository/com/google/guava/failureaccess/1.0.1/failureaccess-1.0.1.jar:/Users/cdornin/.m2/repository/com/google/guava/listenablefuture/9999.0-empty-to-avoid-conflict-with-guava/listenablefuture-9999.0-empty-to-avoid-conflict-with-guava.jar:/Users/cdornin/.m2/repository/com/google/code/findbugs/jsr305/3.0.2/jsr305-3.0.2.jar:/Users/cdornin/.m2/repository/org/checkerframework/checker-qual/2.11.1/checker-qual-2.11.1.jar:/Users/cdornin/.m2/repository/com/google/errorprone/error_prone_annotations/2.3.4/error_prone_annotations-2.3.4.jar:/Users/cdornin/.m2/repository/com/google/j2objc/j2objc-annotations/1.3/j2objc-annotations-1.3.jar:/Users/cdornin/.m2/repository/com/squareup/okhttp3/okhttp/4.8.1/okhttp-4.8.1.jar:/Users/cdornin/.m2/repository/com/squareup/okio/okio/2.7.0/okio-2.7.0.jar:/Users/cdornin/.m2/repository/org/jetbrains/kotlin/kotlin-stdlib-common/1.3.70/kotlin-stdlib-common-1.3.70.jar:/Users/cdornin/.m2/repository/org/jetbrains/kotlin/kotlin-stdlib/1.3.72/kotlin-stdlib-1.3.72.jar:/Users/cdornin/.m2/repository/org/jetbrains/annotations/13.0/annotations-13.0.jar:/Users/cdornin/.m2/repository/com/fasterxml/jackson/core/jackson-annotations/2.11.2/jackson-annotations-2.11.2.jar:/Users/cdornin/.m2/repository/com/fasterxml/jackson/core/jackson-core/2.11.2/jackson-core-2.11.2.jar:/Users/cdornin/.m2/repository/com/fasterxml/jackson/core/jackson-databind/2.11.2/jackson-databind-2.11.2.jar com.amazonaws.transcribe.AmazonTranscribeServiceImpl
log4j:WARN Continuable parsing error 2 and column 30
log4j:WARN Document root element "Configuration", must match DOCTYPE root "null".
log4j:WARN Continuable parsing error 2 and column 30
log4j:WARN Document is invalid: no grammar found.
log4j:ERROR DOM element is - not a <log4j:configuration> element.
log4j:WARN No appenders could be found for logger (com.amazonaws.AmazonWebServiceClient).
log4j:WARN Please initialize the log4j system properly.
log4j:WARN See http://logging.apache.org/log4j/1.2/faq.html#noconfig for more info.
Exception in thread "main" com.amazonaws.services.transcribe.model.AmazonTranscribeException: null (Service: AmazonTranscribe; Status Code: 400; Error Code: null; Request ID: 6BBE51FDC2CA981B; Proxy: null)
at com.amazonaws.http.AmazonHttpClient$RequestExecutor.handleErrorResponse(AmazonHttpClient.java:1819)
at com.amazonaws.http.AmazonHttpClient$RequestExecutor.handleServiceErrorResponse(AmazonHttpClient.java:1403)
at com.amazonaws.http.AmazonHttpClient$RequestExecutor.executeOneRequest(AmazonHttpClient.java:1372)
at com.amazonaws.http.AmazonHttpClient$RequestExecutor.executeHelper(AmazonHttpClient.java:1145)
at com.amazonaws.http.AmazonHttpClient$RequestExecutor.doExecute(AmazonHttpClient.java:802)
at com.amazonaws.http.AmazonHttpClient$RequestExecutor.executeWithTimer(AmazonHttpClient.java:770)
at com.amazonaws.http.AmazonHttpClient$RequestExecutor.execute(AmazonHttpClient.java:744)
at com.amazonaws.http.AmazonHttpClient$RequestExecutor.access$500(AmazonHttpClient.java:704)
at com.amazonaws.http.AmazonHttpClient$RequestExecutionBuilderImpl.execute(AmazonHttpClient.java:686)
at com.amazonaws.http.AmazonHttpClient.execute(AmazonHttpClient.java:550)
at com.amazonaws.http.AmazonHttpClient.execute(AmazonHttpClient.java:530)
at com.amazonaws.services.transcribe.AmazonTranscribeClient.doInvoke(AmazonTranscribeClient.java:1995)
at com.amazonaws.services.transcribe.AmazonTranscribeClient.invoke(AmazonTranscribeClient.java:1962)
at com.amazonaws.services.transcribe.AmazonTranscribeClient.invoke(AmazonTranscribeClient.java:1951)
at com.amazonaws.services.transcribe.AmazonTranscribeClient.executeStartTranscriptionJob(AmazonTranscribeClient.java:1712)
at com.amazonaws.services.transcribe.AmazonTranscribeClient.startTranscriptionJob(AmazonTranscribeClient.java:1681)
at com.amazonaws.transcribe.AmazonTranscribeServiceImpl.callTranscribeService(AmazonTranscribeServiceImpl.java:34)
at com.amazonaws.transcribe.AmazonTranscribeServiceImpl.main(AmazonTranscribeServiceImpl.java:20)
Here is my java code (add your aws key and secret)
package com.amazonaws.transcribe;
import com.amazonaws.ClientConfiguration;
import com.amazonaws.auth.DefaultAWSCredentialsProviderChain;
import com.amazonaws.client.builder.AwsClientBuilder;
import com.amazonaws.services.transcribe.AmazonTranscribe;
import com.amazonaws.services.transcribe.AmazonTranscribeClientBuilder;
import com.amazonaws.services.transcribe.model.Media;
import com.amazonaws.services.transcribe.model.StartTranscriptionJobRequest;
import com.amazonaws.services.transcribe.model.StartTranscriptionJobResult;
/**
* #author ravindu.s
*/
public class AmazonTranscribeServiceImpl {
public static void main(String[] args) throws Exception {
System.setProperty("aws.accessKeyId", "myKey");
System.setProperty("aws.secretAccessKey", "mySecret");
callTranscribeService("https://s3.us-east-1.amazonaws.com/csld8xmsdksdf8s9sk3mmdjsdifkjksdijsldk/Transcribe2.wav");
}
public static void callTranscribeService(String mediaFile) {
ClientConfiguration clientConfig = new ClientConfiguration();
clientConfig.setConnectionTimeout(60000);
clientConfig.setMaxConnections(100);
clientConfig.setSocketTimeout(60000);
AmazonTranscribe transcribeClient = AmazonTranscribeClientBuilder.standard().withCredentials(
DefaultAWSCredentialsProviderChain.getInstance()).withEndpointConfiguration(
new AwsClientBuilder.EndpointConfiguration(mediaFile, "us-east-1")).withClientConfiguration(clientConfig).build();
StartTranscriptionJobRequest request = buildRequest(mediaFile);
StartTranscriptionJobResult response = transcribeClient.startTranscriptionJob(request);
System.out.println(response.getTranscriptionJob().getTranscriptionJobStatus());
}
private static StartTranscriptionJobRequest buildRequest(String mediaFile) {
StartTranscriptionJobRequest request = new StartTranscriptionJobRequest();
request.setMediaSampleRateHertz(16000);
request.setMediaFormat("wav");
request.setLanguageCode("en-US");
request.setTranscriptionJobName("JOB-001");
Media media = new Media();
media.setMediaFileUri(mediaFile);
request.setMedia(media);
return request;
}
}
Here is my pom.xml file
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>play</groupId>
<artifactId>transcribeTest</artifactId>
<version>1.0-SNAPSHOT</version>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>8</source>
<target>8</target>
</configuration>
</plugin>
</plugins>
</build>
<dependencies>
<!--<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-api</artifactId>
<version>5.4.2</version>
<scope>test</scope>
</dependency>-->
<!-- https://mvnrepository.com/artifact/junit/junit -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.13.1</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-engine</artifactId>
<version>5.4.2</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.platform</groupId>
<artifactId>junit-platform-commons</artifactId>
<version>1.4.0</version>
</dependency>
<dependency>
<groupId>org.junit.platform</groupId>
<artifactId>junit-platform-launcher</artifactId>
<version>1.4.0</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>1.7.25</version>
</dependency>
<dependency>
<groupId>software.amazon.awssdk</groupId>
<artifactId>transcribe</artifactId>
<version>2.15.65</version>
</dependency>
<!-- https://mvnrepository.com/artifact/software.amazon.awssdk/transcribestreaming -->
<dependency>
<groupId>software.amazon.awssdk</groupId>
<artifactId>transcribestreaming</artifactId>
<version>2.15.65</version>
</dependency>
<!-- https://mvnrepository.com/artifact/com.amazonaws/aws-java-sdk-s3 -->
<dependency>
<groupId>com.amazonaws</groupId>
<artifactId>aws-java-sdk-s3</artifactId>
<version>1.11.939</version>
</dependency>
<!-- https://mvnrepository.com/artifact/com.amazonaws/aws-java-sdk-transcribe -->
<dependency>
<groupId>com.amazonaws</groupId>
<artifactId>aws-java-sdk-transcribe</artifactId>
<version>1.11.939</version>
</dependency>
<dependency>
<groupId>io.minio</groupId>
<artifactId>minio</artifactId>
<version>8.0.3</version>
</dependency>
</dependencies>
</project>
Here is a Java Code Example that transcribes an audio file located in C:. This is V2.
import org.reactivestreams.Publisher;
import org.reactivestreams.Subscriber;
import org.reactivestreams.Subscription;
import software.amazon.awssdk.core.SdkBytes;
import software.amazon.awssdk.regions.Region;
import software.amazon.awssdk.services.transcribestreaming.TranscribeStreamingAsyncClient;
import software.amazon.awssdk.services.transcribestreaming.model.*;
import javax.sound.sampled.*;
import java.io.*;
import java.net.URISyntaxException;
import java.nio.ByteBuffer;
import java.util.List;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.atomic.AtomicLong;
public class TranscribeStreamingDemoFile {
private static final Region REGION = Region.US_EAST_1;
private static TranscribeStreamingAsyncClient client;
public static void main(String args[]) throws URISyntaxException, ExecutionException, InterruptedException, LineUnavailableException {
client = TranscribeStreamingAsyncClient.builder()
.region(REGION)
.build();
CompletableFuture<Void> result = client.startStreamTranscription(getRequest(16000),
new AudioStreamPublisher(getStreamFromFile()),
getResponseHandler());
result.get();
client.close();
}
private static InputStream getStreamFromFile() {
try {
File inputFile = new File("C:\\test.wav");
InputStream audioStream = new FileInputStream(inputFile);
return audioStream;
} catch (FileNotFoundException e) {
throw new RuntimeException(e);
}
}
private static StartStreamTranscriptionRequest getRequest(Integer mediaSampleRateHertz) {
return StartStreamTranscriptionRequest.builder()
.languageCode(LanguageCode.EN_US)
.mediaEncoding(MediaEncoding.PCM)
.mediaSampleRateHertz(mediaSampleRateHertz)
.build();
}
private static StartStreamTranscriptionResponseHandler getResponseHandler() {
return StartStreamTranscriptionResponseHandler.builder()
.onResponse(r -> {
System.out.println("Received Initial response");
})
.onError(e -> {
System.out.println(e.getMessage());
StringWriter sw = new StringWriter();
e.printStackTrace(new PrintWriter(sw));
System.out.println("Error Occurred: " + sw.toString());
})
.onComplete(() -> {
System.out.println("=== All records stream successfully ===");
})
.subscriber(event -> {
List<Result> results = ((TranscriptEvent) event).transcript().results();
if (results.size() > 0) {
if (!results.get(0).alternatives().get(0).transcript().isEmpty()) {
System.out.println(results.get(0).alternatives().get(0).transcript());
}
}
})
.build();
}
private static class AudioStreamPublisher implements Publisher<AudioStream> {
private final InputStream inputStream;
private static Subscription currentSubscription;
private AudioStreamPublisher(InputStream inputStream) {
this.inputStream = inputStream;
}
#Override
public void subscribe(Subscriber<? super AudioStream> s) {
if (this.currentSubscription == null) {
this.currentSubscription = new SubscriptionImpl(s, inputStream);
} else {
this.currentSubscription.cancel();
this.currentSubscription = new SubscriptionImpl(s, inputStream);
}
s.onSubscribe(currentSubscription);
}
}
public static class SubscriptionImpl implements Subscription {
private static final int CHUNK_SIZE_IN_BYTES = 1024 * 1;
private final Subscriber<? super AudioStream> subscriber;
private final InputStream inputStream;
private ExecutorService executor = Executors.newFixedThreadPool(1);
private AtomicLong demand = new AtomicLong(0);
SubscriptionImpl(Subscriber<? super AudioStream> s, InputStream inputStream) {
this.subscriber = s;
this.inputStream = inputStream;
}
#Override
public void request(long n) {
if (n <= 0) {
subscriber.onError(new IllegalArgumentException("Demand must be positive"));
}
demand.getAndAdd(n);
executor.submit(() -> {
try {
do {
ByteBuffer audioBuffer = getNextEvent();
if (audioBuffer.remaining() > 0) {
AudioEvent audioEvent = audioEventFromBuffer(audioBuffer);
subscriber.onNext(audioEvent);
} else {
subscriber.onComplete();
break;
}
} while (demand.decrementAndGet() > 0);
} catch (Exception e) {
subscriber.onError(e);
}
});
}
#Override
public void cancel() {
executor.shutdown();
}
private ByteBuffer getNextEvent() {
ByteBuffer audioBuffer = null;
byte[] audioBytes = new byte[CHUNK_SIZE_IN_BYTES];
int len = 0;
try {
len = inputStream.read(audioBytes);
if (len <= 0) {
audioBuffer = ByteBuffer.allocate(0);
} else {
audioBuffer = ByteBuffer.wrap(audioBytes, 0, len);
}
} catch (IOException e) {
throw new UncheckedIOException(e);
}
return audioBuffer;
}
private AudioEvent audioEventFromBuffer(ByteBuffer bb) {
return AudioEvent.builder()
.audioChunk(SdkBytes.fromByteBuffer(bb))
.build();
}
}
}
I had a small mistake in my code. This line wasn't necessary and when I removed, it worked:
withEndpointConfiguration(new AwsClientBuilder.EndpointConfiguration(mediaFile, "us-east-1"))
Related
I have below pom.xml file. I want to replace the version of the project which is in line 7.
I will be able to provide<version> tag alone but not complete version details.
Expecting a code which finds the 1st <version> tag line and replace that with <version>1.0.1</version>
I started with the below java code but which is currently replacing the whole version tag in the entire pom.xml.
How do I replace 1st <version> tag line alone with <version>1.0.1</version>
<?xml version="1.0" encoding="UTF-8"?>
<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<modelVersion>4.0.0</modelVersion>
<groupId>com.myspace</groupId>
<artifactId>Test</artifactId>
<version>1.0.0-SNAPSHOT</version>
<packaging>kjar</packaging>
<name>Test</name>
<description></description>
<dependencies>
<dependency>
<groupId>org.kie</groupId>
<artifactId>kie-api</artifactId>
<version>7.46.0.Final</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.kie</groupId>
<artifactId>kie-internal</artifactId>
<version>7.46.0.Final</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.optaplanner</groupId>
<artifactId>optaplanner-core</artifactId>
<version>7.46.0.Final</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.optaplanner</groupId>
<artifactId>optaplanner-persistence-jaxb</artifactId>
<version>7.46.0.Final</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.13.1</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.thoughtworks.xstream</groupId>
<artifactId>xstream</artifactId>
<version>1.4.11.1</version>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.kie</groupId>
<artifactId>kie-maven-plugin</artifactId>
<version>7.46.0.Final</version>
<extensions>true</extensions>
</plugin>
</plugins>
</build>
</project>
Java code
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileWriter;
import java.io.IOException;
import java.util.Scanner;
public class OverwriteLine {
public static void main(String args[]) throws IOException {
//Instantiating the File class
String cloneDirectoryPath = "D:\\project\\localrepo117";
String filePath = cloneDirectoryPath+"\\pom.xml";
//Instantiating the Scanner class to read the file
Scanner sc = new Scanner(new File(filePath));
//instantiating the StringBuffer class
StringBuffer buffer = new StringBuffer();
//Reading lines of the file and appending them to StringBuffer
while (sc.hasNextLine()) {
buffer.append(sc.nextLine()+System.lineSeparator());
}
String fileContents = buffer.toString();
System.out.println("Contents of the file: "+fileContents);
//closing the Scanner object
sc.close();
String oldLine = "<version>";
String newLine = "<version>1.0.1</version>";
//Replacing the old line with new line
fileContents = fileContents.replaceAll(oldLine, newLine);
//instantiating the FileWriter class
FileWriter writer = new FileWriter(filePath);
System.out.println("");
System.out.println("new data: "+fileContents);
writer.append(fileContents);
writer.flush();
}
}
I suggest that you read file "pom.xml", line by line. If the line read is the line you want to change, then change it otherwise leave it as it is. Then write the line that you read to a temporary file. Once you have read all the lines in file "pom.xml", delete it and rename the temporary file to "pom.xml".
The below code does this.
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.StandardOpenOption;
public class OverwriteLine {
public static void main(String[] args) {
Path sourcePath = Path.of("pom.xml");
Path targetPath = Path.of("tmp.xml");
boolean error = false;
try (BufferedReader br = Files.newBufferedReader(sourcePath);
BufferedWriter bw = Files.newBufferedWriter(targetPath,
StandardOpenOption.CREATE,
StandardOpenOption.TRUNCATE_EXISTING,
StandardOpenOption.WRITE)) {
boolean found = false;
String line = br.readLine();
while (line != null) {
if (!found) {
if (line.trim().startsWith("<version>")) {
found = true;
line = line.replace("1.0.0", "1.0.1");
}
}
bw.write(line);
bw.write(System.lineSeparator());
line = br.readLine();
}
}
catch (IOException xIo) {
error = true;
xIo.printStackTrace();
}
if (!error) {
try {
Files.delete(sourcePath);
Files.move(targetPath, sourcePath);
}
catch (IOException xIo) {
xIo.printStackTrace();
}
}
}
}
So I've been working on a simple automation framework that uses excel as data pool. However, while updating the version of my pom.xlm, I've encountered this error in my console:
Cleaning up unclosed ZipFile for archive D:\ExcelData\RPC Standard Form Data1.xlsx
I have no idea what went wrong. This error does not stop the execution and my tests run smoothly. How can I possibly solve this problem. I can't find anything suitable answers
Here my dependencies
<project>
<groupId>com.manuhsolutions</groupId>
<artifactId>Seleniumtest</artifactId>
<version>1.0-SNAPSHOT</version>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.6</source>
<target>1.6</target>
</configuration>
</plugin>
</plugins>
</build>
<dependencies>
<dependency>
<groupId>org.seleniumhq.selenium</groupId>
<artifactId>selenium-java</artifactId>
<version>4.1.0</version>
</dependency>
<dependency>
<groupId>org.seleniumhq.selenium</groupId>
<artifactId>selenium-chrome-driver</artifactId>
<version>4.1.0</version>
</dependency>
<dependency>
<groupId>org.seleniumhq.selenium</groupId>
<artifactId>selenium-support</artifactId>
<version>4.1.0</version>
</dependency>
<dependency>
<groupId>net.sf.opencsv</groupId>
<artifactId>opencsv</artifactId>
<version>2.3</version>
</dependency>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi</artifactId>
<version>5.1.0</version>
</dependency>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml</artifactId>
<version>5.1.0</version>
</dependency>
<dependency>
<groupId>org.testng</groupId>
<artifactId>testng</artifactId>
<version>7.4.0</version>
<scope>test</scope>
</dependency>
</dependencies>
</project>
Here's the method I deal with the excel:
package automationcode;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
public class OpenXlsxFile {
static XSSFWorkbook workbook;
static XSSFSheet sheet;
public OpenXlsxFile (String excelPath, String sheetName) {
try {
workbook = new XSSFWorkbook(excelPath);
sheet = workbook.getSheet(sheetName);
} catch (Exception e) {
e.printStackTrace();
}
}
public static void main (String [] ags) {
getRowCount() ;
getCelldataString(1,1) ;
getcolCount() ;
}
public static int getRowCount() {
int rowCount = 0;
try {
rowCount = sheet.getPhysicalNumberOfRows();
} catch (Exception exp) {
System.out.println(exp.getMessage());
System.out.println(exp.getCause());
exp.printStackTrace();
}
return rowCount;
}
public static String getCelldataString(int rowNum, int colNum) {
String cellData = null;
try {
cellData = sheet.getRow(rowNum).getCell(colNum).getStringCellValue();
} catch (Exception exp) { }
return cellData ;
}
public static int getcolCount() {
int colCount = 0;
try {
colCount = sheet.getRow(0).getPhysicalNumberOfCells();
} catch (Exception exp) {
System.out.println(exp.getMessage());
System.out.println(exp.getCause());
exp.printStackTrace();
}
return colCount ;
}
}
I want to create kafka topic in Java. I have a sample code from stackoverflow. But the problem is that I couldn't import ZKStringSerializer$ and ZkUtils. I have all maven dependencies. What is the reason? Her is the code:
import kafka.admin.AdminUtils;
import kafka.utils.ZKStringSerializer$;
import kafka.utils.ZkUtils;
import org.I0Itec.zkclient.ZkClient;
import org.I0Itec.zkclient.ZkConnection;
public class CreateKafkaTopic {
public static void main(String[] args) {
ZkClient zkClient = null;
ZkUtils zkUtils = null;
try {
String zookeeperHosts = "192.168.20.1:2181"; // If multiple zookeeper then -> String zookeeperHosts = "192.168.20.1:2181,192.168.20.2:2181";
int sessionTimeOutInMs = 15 * 1000; // 15 secs
int connectionTimeOutInMs = 10 * 1000; // 10 secs
zkClient = new ZkClient(zookeeperHosts, sessionTimeOutInMs, connectionTimeOutInMs, ZKStringSerializer$.MODULE$);
zkUtils = new ZkUtils(zkClient, new ZkConnection(zookeeperHosts), false);
String topicName = "testTopic";
int noOfPartitions = 2;
int noOfReplication = 3;
Properties topicConfiguration = new Properties();
AdminUtils.createTopic(zkUtils, topicName, noOfPartitions, noOfReplication, topicConfiguration);
} catch (Exception ex) {
ex.printStackTrace();
} finally {
if (zkClient != null) {
zkClient.close();
}
}
}
}
Here is maven dependency:
<!-- https://mvnrepository.com/artifact/org.apache.kafka/kafka -->
<dependency>
<groupId>org.apache.kafka</groupId>
<artifactId>kafka_2.13</artifactId>
<version>2.6.0</version>
</dependency>
<!-- https://mvnrepository.com/artifact/com.101tec/zkclient -->
<dependency>
<groupId>com.101tec</groupId>
<artifactId>zkclient</artifactId>
<version>0.11</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.apache.kafka/kafka-streams-test-utils -->
<dependency>
<groupId>org.apache.kafka</groupId>
<artifactId>kafka-streams-test-utils</artifactId>
<version>2.7.0</version>
</dependency>
I assume you copied from this post? If so, read the very top of that accepted answer.
Zookeeper is a deprecated method to create topics.
Use AdminClient.createTopics or a higher-level framework like dropwizard-kafka configuration or spring-kafka's #Bean to create topics
Also, use kafka-clients dependency, not the kafka_[scala.version] depdendency
I am learning Protocol Buffer in Java. After basic serialization/deserialization, I am attempting to put compression.
In the provided code, I tried to use GZIP but while deserializing, it reads one extra record. It can be seen in System.out printing an extra "," at end.
This problem does not happen when using same code, but with Snappy (Commented in code below). Any suggestions if I am doing something wrong? Or if I can bypass the problem.
Output with GZIP:
id0,NAME0
,
Output with Snappy:
id0,NAME0
Code:
package testPkg;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.zip.GZIPInputStream;
import java.util.zip.GZIPOutputStream;
import org.xerial.snappy.SnappyInputStream;
import org.xerial.snappy.SnappyOutputStream;
public class TestProtoBuf {
public static String fileNm = "C:/testFile";
public static void main(String[] args) throws IOException {
// creating data
List<DataClass> list = new ArrayList<>();
for (int i = 0; i < 1; i++) {
list.add(new DataClass("id" + i, "NAME" + i));
}
// writing data
try (OutputStream os = new GZIPOutputStream(new BufferedOutputStream(new FileOutputStream(fileNm)))
/*OutputStream os = new SnappyOutputStream(new BufferedOutputStream(new FileOutputStream(fileNm)))*/) {
for (DataClass dc : list) {
DataClassProtoBufProxy.DataClass.Builder bld = DataClassProtoBufProxy.DataClass.newBuilder();
bld.setId(dc.id);
bld.setName(dc.name);
bld.build().writeDelimitedTo(os);
}
os.flush();
}
// reading data
try (InputStream is = new GZIPInputStream(new BufferedInputStream(new FileInputStream(fileNm)))
/*InputStream is = new SnappyInputStream(new BufferedInputStream(new FileInputStream(fileNm)))*/) {
while (is.available() > 0) {
DataClassProtoBufProxy.DataClass.Builder bld = DataClassProtoBufProxy.DataClass.newBuilder();
bld.mergeDelimitedFrom(is);
DataClassProtoBufProxy.DataClass dc = bld.build();
System.out.println(dc.getId() + "," + dc.getName());
}
}
}
static class DataClass {
private String id;
private String name;
DataClass() {
id = null;
name = null;
}
DataClass(String id, String name) {
this.id = id;
this.name = name;
}
}
}
The proto file:
// [START declaration]
syntax = "proto3";
package testPkg;
// [END declaration]
// [START java_declaration]
option java_package = "testPkg";
option java_outer_classname = "DataClassProtoBufProxy";
// [END java_declaration]
// [START messages]
message DataClass {
string id = 1;
string name = 20;
}
// [END messages]
Maven dependencies:
<!-- https://mvnrepository.com/artifact/com.google.protobuf/protobuf-java -->
<dependency>
<groupId>com.google.protobuf</groupId>
<artifactId>protobuf-java</artifactId>
<version>3.2.0</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.xerial.snappy/snappy-java -->
<dependency>
<groupId>org.xerial.snappy</groupId>
<artifactId>snappy-java</artifactId>
<version>1.1.2.6</version>
</dependency>
I am trying to use HTTP/2 to send an apple notification to my device on production.
I am passing this -Xbootclasspath/p:/home/mohamed/Desktop/alpn-boot-8.1.9.v20160720.jar as a Default VM arguments in eclipse.
Here are the code which i am using now:
public static void pushoNotification() {
try {
// create a low-level Jetty HTTP/2 client
HTTP2Client lowLevelClient = new HTTP2Client();
lowLevelClient.start();
// APNs requires the use of HPACK (header compression for HTTP/2), which prevents repeated header keys and values.
KeyStore ks = KeyStore.getInstance("PKCS12");
// Ensure that the password is the same as the one used later in setKeyStorePassword()
ks.load(PushNotifications.class.getClassLoader().getResourceAsStream("Prod2.p12"), "a12B34".toCharArray());
SslContextFactory ssl = new SslContextFactory(true);
ssl.setKeyStore(ks);
ssl.setKeyStorePassword("a12B34");
// create a high-level Jetty client
HttpClient client = new HttpClient(new HttpClientTransportOverHTTP2(lowLevelClient), ssl);
client.start();
// request-response exchange
ContentResponse response = client.POST("https://api.push.apple.com").path("/3/device/19297dba97212ac6fd16b9cd50f2d86629aed0e49576b2b52ed05086087da802")
.content(new StringContentProvider("{ \"aps\" : { \"alert\" : \"Hello\" } }")).send();
response.toString();
client.stop();
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
}
My dependencies
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.21</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-simple</artifactId>
<version>1.7.21</version>
</dependency>
<dependency>
<groupId>org.eclipse.jetty.http2</groupId>
<artifactId>http2-http-client-transport</artifactId>
<version>9.4.0.M1</version>
</dependency>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-http</artifactId>
<version>9.4.0.M1</version>
</dependency>
<dependency>
<groupId>org.eclipse.jetty.http2</groupId>
<artifactId>http2-client</artifactId>
<version>9.4.0.M1</version>
</dependency>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-client</artifactId>
<version>9.4.0.M1</version>
</dependency>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-alpn-client</artifactId>
<version>9.4.0.M1</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.mortbay.jetty.alpn</groupId>
<artifactId>alpn-boot</artifactId>
<version>8.1.9.v20160720</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>2.8.2</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.8.2</version>
</dependency>
<dependency>
<groupId>com.squareup.okhttp3</groupId>
<artifactId>okhttp</artifactId>
<version>3.4.1</version>
</dependency>
but when i run this method from main method, it throws java.nio.channels.ClosedChannelException
Also i got this in eclipse console
INFO org.eclipse.jetty.http2.HTTP2Session - Failure while notifying listener org.eclipse.jetty.http2.client.http.HttpClientTransportOverHTTP2$SessionListenerPromise#87eaf9c
Any idea?
Thanks
I am pasting my answer now after about 3 years and 6 month just to help any one get same error, actually i can't recall how i fixed this issue but here are a working code which i am using now...
import java.io.IOException;
import java.io.InputStream;
import java.net.InetSocketAddress;
import java.nio.charset.Charset;
import java.security.KeyStore;
import java.util.Date;
import java.util.List;
import java.util.Properties;
import java.util.concurrent.TimeUnit;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.annotation.PostConstruct;
import javax.inject.Singleton;
import javax.ws.rs.Consumes;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.QueryParam;
import javax.ws.rs.core.CacheControl;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import org.eclipse.jetty.client.HttpClient;
import org.eclipse.jetty.client.api.ContentResponse;
import org.eclipse.jetty.client.api.Request;
import org.eclipse.jetty.client.util.StringContentProvider;
import org.eclipse.jetty.http2.api.Session;
import org.eclipse.jetty.http2.api.server.ServerSessionListener;
import org.eclipse.jetty.http2.client.HTTP2Client;
import org.eclipse.jetty.http2.client.http.HttpClientTransportOverHTTP2;
import org.eclipse.jetty.util.FuturePromise;
import org.eclipse.jetty.util.ssl.SslContextFactory;
import com.fasterxml.jackson.annotation.JsonInclude.Include;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.myproject.path.model.APNSObject;
public void sendIOSNotification(APNSObject apnsObject, List<String> deviceIds, String notificationType) {
HTTP2Client lowLevelClient = null;
HttpClient client = null;
String hostname = null;
InputStream inputStream = null;
try {
lowLevelClient = new HTTP2Client(); // create a low-level Jetty HTTP/2 client
lowLevelClient.start();
// APNs requires the use of HPACK (header compression for HTTP/2), which prevents repeated header keys and values.
KeyStore ks = KeyStore.getInstance(KEYSTORE_TYPE);
inputStream = getClass().getClassLoader().getResourceAsStream(APPLE_CERTIFICATE_PATH);
// Ensure that the password is the same as the one used later in setKeyStorePassword()
ks.load(inputStream, APPLE_CERTIFICATE_PASSWORD.toCharArray());
inputStream.close();
SslContextFactory ssl = new SslContextFactory(true);
ssl.setKeyStore(ks);
ssl.setKeyStorePassword(APPLE_CERTIFICATE_PASSWORD);
FuturePromise<Session> sessionPromise = new FuturePromise<>();
if (notificationType != null && notificationType.trim().equalsIgnoreCase("Development"))
hostname = APPLE_NOTIFICATION_DEVELOPMENT_HOSTNAME;
else
hostname = APPLE_NOTIFICATION_PRODUCTION_HOSTNAME;
lowLevelClient.connect(ssl, new InetSocketAddress(hostname, Integer.parseInt(APPLE_NOTIFICATION_PORT)), new ServerSessionListener.Adapter(), sessionPromise);
// create a high-level Jetty client
client = new HttpClient(new HttpClientTransportOverHTTP2(lowLevelClient), ssl);
client.start();
// logger.info("Start Sending Notification.");
for (String token : deviceIds) {
ObjectMapper mapper = new ObjectMapper();
String fcmJsonObject = mapper.setSerializationInclusion(Include.NON_NULL).setSerializationInclusion(Include.NON_EMPTY).writeValueAsString(apnsObject);
Request request = client.POST("https://" + hostname).timeout(20, TimeUnit.SECONDS).path("/3/device/" + token)
.content(new StringContentProvider(fcmJsonObject, Charset.forName("UTF-8")));
request = request.header("apns-topic", APPLE_APNS_TOPIC);
ContentResponse response = request.send();
// For development mode if it's not passed in parameters
if (response.getStatus() == 400 && !hostname.equals(APPLE_NOTIFICATION_DEVELOPMENT_HOSTNAME)) {
request = client.POST("https://" + APPLE_NOTIFICATION_DEVELOPMENT_HOSTNAME).timeout(20, TimeUnit.SECONDS).path("/3/device/" + token)
.content(new StringContentProvider(fcmJsonObject, Charset.forName("UTF-8")));
request = request.header("apns-topic", APPLE_APNS_TOPIC);
response = request.send();
logger.info("Sending notification to '" + token + "' in debugging mode...");
}
if (response.getStatus() == 200)
logger.info("Date: " + new Date() + " Notification sent successfully to '" + token + "' With Response Status: " + response.getStatus());
else
logger.warning("Sending Notification to token '" + token + "' Failed :( >> Response Status: " + response.getStatus() + "\nReason: " + response.getReason());
}
logger.info("End Sending Notification.");
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
if (lowLevelClient != null && !lowLevelClient.isStopped())
lowLevelClient.stop();
if (client != null && !client.isStopped())
client.stop();
} catch (Exception e) {
e.printStackTrace();
}
try {
if (inputStream != null)
inputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
APNSObject.java class
import java.io.Serializable;
public class APNSObject implements Serializable {
// {\"aps\":{\"alert\":{" + messageTitle + "\"body\":\"" + alert + "\"}, \"sound\":\"default\"}" + payload + "}
private static final long serialVersionUID = 1L;
private Aps aps;
private TripBruEntity payload;// Our custom JSON Object
public APNSObject() {
}
public APNSObject(String title, String body, TripBruEntity payload) {
this(title, body, null, payload);
}
public APNSObject(String title, String body, String sound, TripBruEntity payload) {
aps = new Aps(title, body, sound);
this.payload = payload;
}
public Aps getAps() {
return aps;
}
public void setAps(Aps aps) {
this.aps = aps;
}
public TripBruEntity getPayload() {
return payload;
}
public void setPayload(TripBruEntity payload) {
this.payload = payload;
}
static class Aps {
private Alert alert;
private String sound;
public Aps() {
}
public Aps(String title, String body, String sound) {
this.alert = new Alert(title, body);
this.sound = sound == null || sound.isEmpty() ? "default" : sound;
}
public Alert getAlert() {
return alert;
}
public void setAlert(Alert alert) {
this.alert = alert;
}
public String getSound() {
return sound;
}
public void setSound(String sound) {
this.sound = sound;
}
static class Alert {
private String title;
private String body;
public Alert() {
}
public Alert(String title, String body) {
this.title = title;
this.body = body;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getBody() {
return body;
}
public void setBody(String body) {
this.body = body;
}
}
}
}
and here are my configuration file:
APPLE_CERTIFICATE_PATH=/my/apply/certificate/path/so/plz/change/it/Certificates.p12
APPLE_CERTIFICATE_PASSWORD=myPassword(plz change it)
KEYSTORE_TYPE=PKCS12
APPLE_NOTIFICATION_DEVELOPMENT_HOSTNAME=api.development.push.apple.com
APPLE_NOTIFICATION_PRODUCTION_HOSTNAME=api.push.apple.com
APPLE_NOTIFICATION_PORT=2197
APPLE_APNS_TOPIC=MyAPNS_Topic(plz change it)
Last thing, here are jars i used in my project: