how to truncate long exception message in java - java

I have long hierarchy of exceptions, one of it add long message with binary data. I can't change it in throw place, since it's in library. How can i truncate it, without losing another exceptions messages?
code example:
throw new RuntimeException("msg",
new RuntimeException(generateLongErrorMessage(),
new RuntimeException("short message",
new RuntimeException("important message"))
)
);
desired output:
Exception in thread "main" java.lang.RuntimeException: msg
at xxx.excpetionMessageTruncator(Erofeev.java:18)
at xxx.main(Erofeev.java:14)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:120)
Caused by: java.lang.RuntimeException: long message long message ...(truncated, original size: 100)
... 7 more
Caused by: java.lang.RuntimeException: short message
... 7 more
Caused by: java.lang.RuntimeException: important message
... 7 more

Update:
I see two different ways to do this, depending on your needs. I would prefer solution 2, as it is less invasive and allows all parts of the code to work with the complete exception.
1, one exception type only, no logger changes required:
Catch the exception and copy the whole stack exception by exception to set a shorter message:
private static RuntimeException truncate(RuntimeException rt) {
Stack<Throwable> causeStack = new Stack<>();
Throwable currentEx = rt;
while(currentEx != null) {
causeStack.push(currentEx);
currentEx = currentEx.getCause();
}
RuntimeException newEx = null;
while (!causeStack.isEmpty()) {
Throwable t = causeStack.pop();
newEx = new RuntimeException(truncateMessage(t.getMessage()), newEx);
newEx.setStackTrace(t.getStackTrace());
}
return newEx;
}
private static String truncateMessage(String message) {
if (message.length() < 25) {
return message;
}
return message.substring(0, 25) + "...";
}
While you can use it on any type of exception, the result will always be a stack of runtime exceptions. If that is not desireable you can go with reflections + generics to create a new exception of the same type.
If you only have combinations of message / cause inside the constructor this will be manageable, but keep in mind that there are custom expceptions as well.
2, Custom Exception Handler (if you are not able to catch the exception for whatever reason)
See http://docs.oracle.com/javase/1.5.0/docs/api/java/lang/Thread.UncaughtExceptionHandler.html to set a threads exception handler. From there you can pass the exception to your logger. Then you can perform the truncation in the logger.

Related

Can't use "Handler" approach to adding a URLStreamHandler in AWS Lambda

I'm currently trying to add a URLStreamHandler so I can handle URLs with custom protocols. This works fine when run locally. When deployed to AWS Lambda I get:
java.net.MalformedURLException: unknown protocol: baas
I'm following the "Handler" approach to registering the URLStreamHandler.
I even went as far as copying the code from URL.getURLStreamHandler(String) and added logging into my own code that is run by Lambda:
(Note: this is from the Java 8 source - I realise now that this might not be representative because AWS Lambda uses a Java 11 runtime).
URLStreamHandler handler = null;
String packagePrefixList = null;
packagePrefixList
= java.security.AccessController.doPrivileged(
new sun.security.action.GetPropertyAction(
"java.protocol.handler.pkgs",""));
if (packagePrefixList != "") {
packagePrefixList += "|";
}
// REMIND: decide whether to allow the "null" class prefix
// or not.
packagePrefixList += "sun.net.www.protocol";
LOG.debug("packagePrefixList: " + packagePrefixList);
StringTokenizer packagePrefixIter =
new StringTokenizer(packagePrefixList, "|");
while (handler == null &&
packagePrefixIter.hasMoreTokens()) {
String packagePrefix =
packagePrefixIter.nextToken().trim();
try {
String clsName = packagePrefix + "." + "baas" +
".Handler";
Class<?> cls = null;
LOG.debug("Try " + clsName);
try {
cls = Class.forName(clsName);
} catch (ClassNotFoundException e) {
ClassLoader cl = ClassLoader.getSystemClassLoader();
if (cl != null) {
cls = cl.loadClass(clsName);
}
}
if (cls != null) {
LOG.debug("Instantiate " + clsName);
handler =
(URLStreamHandler)cls.newInstance();
}
} catch (Exception e) {
// any number of exceptions can get thrown here
LOG.debug(e);
}
}
This prints (in Cloudwatch logs):
packagePrefixList: com.elsten.bliss|sun.net.www.protocol (BaasDriver.java:94, thread main)
Try com.elsten.bliss.baas.Handler (BaasDriver.java:108, thread main)
Instantiate com.elsten.bliss.baas.Handler (BaasDriver.java:118, thread main)
com.elsten.bliss.baas.Handler constructor (Handler.java:55, thread main)
So, when run from my own code, in Lambda, it works.
However, the very next line of logging:
java.lang.IllegalArgumentException: URL is malformed: baas://folder: java.lang.RuntimeException
java.lang.RuntimeException: java.lang.IllegalArgumentException: URL is malformed: baas://folder
...
Caused by: java.net.MalformedURLException: unknown protocol: baas
at java.base/java.net.URL.<init>(Unknown Source)
at java.base/java.net.URL.<init>(Unknown Source)
at java.base/java.net.URL.<init>(Unknown Source)
So it seems odd the same code is failing when run in URL. The main difference I can think of is the parent classloader used to load URL and my code are different, and so there's some sort of class loading issue.
The SPI approach can't be used because Lambda doesn't extract META-INF folders!
Initially I thought the old URL.setURLStreamHandlerFactory(URLStreamHandlerFactory) approach was to be avoided, but it turns out this has been improved in recent Java versions, and so I have fallen back to that.
Specifically, a default fallback URLStreamHandlerFactory which is capable of handling streams to http, https, file et al is used as a fallback if the custom one provided cannot handle a stream.
This is a workaround though - it would be interesting to know why the class cannot be loaded.

Why this exception is getting occurred while running the java code with Spark and Stanford NLP?

Here is my code:
try
{
Dataset<Row> df = spark.sql("select answer from health where limit 1");
nameAndCity = df.toJavaRDD().map(new Function<Row, String>() {
// #Override
public String call(Row row) {
return row.getString(0);
}
}).collect();
}
catch (Exception AnalysisException)
{
System.out.print("\nTable is not found\n");
}
spark.close();
System.out.println("Spark Done....!");
for (String name : nameAndCity)
{
Annotation document = new Annotation(name);
Properties props = new Properties();
props.setProperty("annotators", "tokenize,ssplit,pos,lemma,ner,parse,sentiment");
//props.setProperty("parse.binaryTrees","true");
StanfordCoreNLP pipeline = new StanfordCoreNLP(props);
pipeline.annotate(document);
for (CoreMap sentence : document.get(CoreAnnotations.SentencesAnnotation.class)) {
System.out.println("---");
System.out.println("Sentence Analyzed: " + " " + sentence.get(CoreAnnotations.TextAnnotation.class));
System.out.println("Reflected sentiment: " + " " + sentence.get(SentimentCoreAnnotations.SentimentClass.class));
}
}
After running this code, I get the following exception:
Exception in thread "main" edu.stanford.nlp.util.ReflectionLoading$ReflectionLoadingException: Error creating edu.stanford.nlp.time.TimeExpressionExtractorImpl
at edu.stanford.nlp.util.ReflectionLoading.loadByReflection(ReflectionLoading.java:40)
at edu.stanford.nlp.time.TimeExpressionExtractorFactory.create(TimeExpressionExtractorFactory.java:57)
at edu.stanford.nlp.time.TimeExpressionExtractorFactory.createExtractor(TimeExpressionExtractorFactory.java:38)
at edu.stanford.nlp.ie.regexp.NumberSequenceClassifier.<init>(NumberSequenceClassifier.java:86)
at edu.stanford.nlp.ie.NERClassifierCombiner.<init>(NERClassifierCombiner.java:136)
at edu.stanford.nlp.pipeline.AnnotatorImplementations.ner(AnnotatorImplementations.java:121)
at edu.stanford.nlp.pipeline.AnnotatorFactories$6.create(AnnotatorFactories.java:273)
at edu.stanford.nlp.pipeline.AnnotatorPool.get(AnnotatorPool.java:152)
at edu.stanford.nlp.pipeline.StanfordCoreNLP.construct(StanfordCoreNLP.java:451)
at edu.stanford.nlp.pipeline.StanfordCoreNLP.<init>(StanfordCoreNLP.java:154)
at edu.stanford.nlp.pipeline.StanfordCoreNLP.<init>(StanfordCoreNLP.java:150)
at edu.stanford.nlp.pipeline.StanfordCoreNLP.<init>(StanfordCoreNLP.java:137)
at spark.sparkhive.queryhive.main(queryhive.java:64)
Caused by: edu.stanford.nlp.util.MetaClass$ClassCreationException: MetaClass couldn't create public edu.stanford.nlp.time.TimeExpressionExtractorImpl(java.lang.String,java.util.Properties) with args [sutime, {}]
at edu.stanford.nlp.util.MetaClass$ClassFactory.createInstance(MetaClass.java:237)
at edu.stanford.nlp.util.MetaClass.createInstance(MetaClass.java:382)
at edu.stanford.nlp.util.ReflectionLoading.loadByReflection(ReflectionLoading.java:38)
... 12 more
Caused by: java.lang.reflect.InvocationTargetException
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
at java.lang.reflect.Constructor.newInstance(Constructor.java:423)
at edu.stanford.nlp.util.MetaClass$ClassFactory.createInstance(MetaClass.java:233)
... 14 more
Caused by: java.lang.NoClassDefFoundError: de/jollyday/ManagerParameter
at java.lang.Class.forName0(Native Method)
at java.lang.Class.forName(Class.java:264)
at edu.stanford.nlp.time.Options.<init>(Options.java:87)
at edu.stanford.nlp.time.TimeExpressionExtractorImpl.init(TimeExpressionExtractorImpl.java:44)
at edu.stanford.nlp.time.TimeExpressionExtractorImpl.<init>(TimeExpressionExtractorImpl.java:39)
... 19 more
Caused by: java.lang.ClassNotFoundException: de.jollyday.ManagerParameter
at java.net.URLClassLoader.findClass(URLClassLoader.java:381)
at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:331)
at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
... 24 more
17/02/22 18:26:39 INFO ShutdownHookManager: Shutdown hook called
17/02/22 18:26:39 INFO ShutdownHookManager: Deleting directory /tmp/spark-23b5fac2-27ec-44a6-9ff7-cb2b8bfd8753
Why I am getting this exception and what I should do to resolve it?
This one is the source of your trouble:
java.lang.NoClassDefFoundError: de/jollyday/ManagerParameter
Your program is looking for this class but can't find it. Check your classpath.
You can ignore the preceding exceptions in the output because they're just reactions to the original exception.
ReflectionLoadingException is thrown by a method called loadByReflection, so it seems to be a wrapper exception of some kind and unlikely to tell you much.
Then we have ClassCreationException thrown by createInstance, kind of the same situation. In general if you have a method called doSomething that throws DoSomethingException, the exception is either going to tell you exactly what the problem is ("x must be >= 100") or wrap the actual exception.
InvocationTargetException is just the exception that the JVM throws when you try to invoke a method using reflection and that method throws an exception. Again it's just a wrapper for the actual exception.
Finally we get to the actual exception, NoClassDefFoundError.

Unable to call DOC_INFO_BY_NAME from a Custom WCC Java Service

I'm creating a Custom Java Component for oracle-ucm to do some processing based on passed in Excel Files. The files are keyed off of Content ID.
one of the first things the application does after reading the excel file is call DOC_INFO_BY_NAME.
In short: Why can't DOC_INFO_BY_NAME by name find dProcessingState and how do I fix it?
Full Details Below
However, when I do I get the following Error Message:
Error getting DOC_INFO for 'LOCALHOST16200000001'. Unable to retrieve information for 'LOCALHOST16200000001'. Unable to retrieve file format information. Cannot find the parameter 'dProcessingState'. [ Details ]
An error has occurred. The stack trace below shows more information.
!$Error getting DOC_INFO for 'LOCALHOST16200000001'.!csUnableToGetRevInfo2,LOCALHOST16200000001!csUnableToGetFileFormatInfo!syParameterNotFound,dProcessingState
intradoc.common.ServiceException: !csUnableToGetRevInfo2,LOCALHOST16200000001!csUnableToGetFileFormatInfo
at intradoc.server.ServiceRequestImplementor.buildServiceException(ServiceRequestImplementor.java:2176)
at intradoc.server.Service.buildServiceException(Service.java:2404)
at intradoc.server.Service.createServiceExceptionEx(Service.java:2398)
at intradoc.server.Service.createServiceException(Service.java:2393)
at intradoc.server.DocCommonHandler.getDocFormats(DocCommonHandler.java:271)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at intradoc.common.IdcMethodHolder.invokeMethod(IdcMethodHolder.java:86)
at intradoc.common.ClassHelperUtils.executeMethodReportStatus(ClassHelperUtils.java:324)
at intradoc.server.ServiceHandler.executeAction(ServiceHandler.java:79)
at intradoc.server.Service.doCodeEx(Service.java:622)
at intradoc.server.Service.doCode(Service.java:594)
at intradoc.server.ServiceRequestImplementor.doAction(ServiceRequestImplementor.java:1693)
at intradoc.server.Service.doAction(Service.java:566)
at intradoc.server.ServiceRequestImplementor.doActions(ServiceRequestImplementor.java:1483)
at intradoc.server.Service.doActions(Service.java:561)
at intradoc.server.ServiceRequestImplementor.executeActions(ServiceRequestImplementor.java:1415)
at intradoc.server.Service.executeActions(Service.java:547)
at intradoc.server.ServiceRequestImplementor.doRequestInternalEx(ServiceRequestImplementor.java:958)
at intradoc.server.ServiceRequestImplementor.executeServiceTopLevelSimple(ServiceRequestImplementor.java:1070)
at com.lowes.content.edam.massMetaDataUpdate.service.types.ServicesWrapper.executeService(ServicesWrapper.java:139)
at com.lowes.content.edam.massMetaDataUpdate.service.file.GetFileService.getDocInfo(GetFileService.java:478)
at com.lowes.content.edam.massMetaDataUpdate.service.ServiceFieldMapper.getMappings(ServiceFieldMapper.java:76)
at com.lowes.content.edam.massMetaDataUpdate.file.mapper.impl.FieldMapWorker.doInBackground(FieldMapWorker.java:107)
at com.lowes.content.edam.massMetaDataUpdate.file.mapper.impl.FieldMapWorker.doInBackground(FieldMapWorker.java:37)
at javax.swing.SwingWorker$1.call(SwingWorker.java:277)
at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:303)
at java.util.concurrent.FutureTask.run(FutureTask.java:138)
at javax.swing.SwingWorker.run(SwingWorker.java:316)
at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:895)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:918)
at java.lang.Thread.run(Thread.java:662)
Caused by: intradoc.data.DataException: !syParameterNotFound,dProcessingState
at intradoc.data.DataBinder.getEx(DataBinder.java:1258)
at intradoc.data.DataBinder.get(DataBinder.java:1057)
at intradoc.server.DocCommonHandler.getProcessingState(DocCommonHandler.java:277)
at intradoc.server.DocCommonHandler.getDocFormats(DocCommonHandler.java:184)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at intradoc.common.IdcMethodHolder.invokeMethod(IdcMethodHolder.java:87)
at intradoc.common.ClassHelperUtils.executeMethodReportStatus(ClassHelperUtils.java:324)
at intradoc.server.ServiceHandler.executeAction(ServiceHandler.java:79)
at intradoc.server.Service.doCodeEx(Service.java:622)
at intradoc.server.Service.doCode(Service.java:595)
... 20 more
I've tried multiple ways of calling the additional service.
currently I'm using:
public DataBinder executeService(DataBinder binder, Workspace workspace)
throws DataException, ServiceException
{
final String serviceName = binder.getLocal(Services.IdcService);
//check for REMOTE_USER
String username = binder.getEnvironmentValue("REMOTE_USER");
if ( null == username || "".equals(username.trim()))
{
log.warn("username not found, searching the binder.");
try { username = binder.get("dUser"); }
catch (DataException de) { log.error("Unable to get Username.", de); }
if ( null != username && !"".equals(username.trim()))
{ binder.setEnvironmentValue("REMOTE_USER", username); }
else { throw new IllegalStateException("Username required!"); }
}
//clear idcToken
binder.getLocalData().remove("idcToken");
log.info("About to run '" + serviceName + "' as '" + username +"'");
try
{
log.info("Calling service " + serviceName + ": "
+ binder.getLocalData().toString());
// Execute service
service.createRequestImplementor();
service.getRequestImplementor()
.executeServiceTopLevelSimple(binder, serviceName,
service.getUserData());
log.info("Finished calling service");
return service.getBinder();
}
catch (DataException e)
{
String msg = "Unexpected Failure executing service '"+serviceName+"'";
log.info(msg, e);
throw e; //log and duck
}
}
So why can't WCC find dProcessingState, and how do I fix it?
Your way of calling the service is fairly standard and I don't think that is the reason. My first guess is that your other code is interfering with your call to DOC_INFO_BY_NAME. If you disable all your other custom code (perhaps easier said than done) and call the service in a clean component, then I think it'll work. Second candidate is to reconsider if your custom service really should be a FileService. Not sure if that affects the result, but perhaps worth a try.
It almost seems like a bug to me.
getProcessingState() is called from getDocFormats() which is called from the DOC_INFO* service.
The code for getProcessingState() first retrieves dProcessingState.
String curProcState = this.m_binder.get("dProcessingState");
Then, it checks if this is null:
if (curProcState != null)
However, it never gets to the null check. This is because DataBinder.get() is requiring a value for any key passed in (in this case dProcessingState.)
Trying setting dProcessingState to a value in the DataBinder before calling the service.
binder.setLocal("dProcessingState", "ignore");
The problem was totally my fault. I had tried to be fancy, and extend Databinder to make it easier for me to use. Turns out my extension was faulty.
Rolling back to the default and double checking my data in the binder fixed it.

program throws CharConversionException in Java?

I am getting the below mentioned error in my catch block when i print using e.printStackTrace();This only occurs for few records when i read it from the DB2 database. So basically only few records throw the error rest work fine.
I have almost 1000 line of code and i am not sure were do i start from in order to understand/debug this error ? IS there any hint that i can get from the error message i should use to solve it ?
from the method getDataFromEMPHCForEmployeeDetails()----- com.ibm.db2.jcc.am.SqlException: [jcc][t4][1065][12306][3.63.123] Caught java.io.CharConversionException. See attached Throwable for details. ERRORCODE=-4220, SQLSTATE=null
at com.ibm.db2.jcc.am.fd.a(fd.java:663)
at com.ibm.db2.jcc.am.fd.a(fd.java:60)
at com.ibm.db2.jcc.am.fd.a(fd.java:112)
at com.ibm.db2.jcc.am.ic.a(ic.java:2820)
at com.ibm.db2.jcc.am.ic.p(ic.java:521)
at com.ibm.db2.jcc.am.ic.N(ic.java:1558)
at com.ibm.db2.jcc.am.vn.e(vn.java:1147)
at com.ibm.db2.jcc.am.vn.getString(vn.java:1122)
at com.ibm.db2.jcc.am.vn.getString(vn.java:1698)
at CreateChart.getDataFromEMPHCForEmployeeDetails(CreateChart.java:330)
at CreateChart.iterateDirectReportNamesFromArrayList(CreateChart.java:594)
at CreateChart.getDataFromEMPHCForDirectReport(CreateChart.java:295)
at CreateChart.iterateSecondLineManagerNamesFromArrayList(CreateChart.java:562)
at CreateChart.getDataFromEMPHCForSecondLine(CreateChart.java:251)
at CreateChart.iterateThirdLineManagerNamesFromArrayList(CreateChart.java:533)
at CreateChart.getDataFromEMPHCForThirdLine(CreateChart.java:208)
at CreateChart.iterateDirectorNamesFromArrayList(CreateChart.java:506)
at CreateChart.getDataFromEMPHCForDirector(CreateChart.java:168)
at CreateChart.iterateVPNamesFromArrayList(CreateChart.java:472)
at CreateChart.getDataFromEMPHCForVp(CreateChart.java:126)
at CreateChart.iterateFuncVPNamesFromArrayList(CreateChart.java:434)
at CreateChart.getDataFromEMPHCForFuncVp(CreateChart.java:95)
at CreateChart.main(CreateChart.java:613)
Caused by: java.nio.charset.MalformedInputException: Input length = 186
at com.ibm.db2.jcc.am.t.a(t.java:19)
at com.ibm.db2.jcc.am.ic.a(ic.java:2816)
... 19 more
Caused by: sun.io.MalformedInputException
at sun.io.ByteToCharUTF8.convert(Unknown Source)
at com.ibm.db2.jcc.am.t.a(t.java:16)
... 20 more
.
public void getDataFromEMPHCForEmployeeDetails(String funcvp_name11, String vp_name11, String director_name11, String thirdline_name11, String secondline_name11, String directreport_name11){
String myQuery11;
if(directreport_name11 == ""){directreport_name11 = " AND DIRECT_REPORT IS NULL";}
else{directreport_name11 =" AND DIRECT_REPORT ='"+ directreport_name11.replace("'", "''")+"'";}
myQuery11 = "SELECT DISTINCT(SERIAL_NUM) FROM DB2INST1.EMP_HC WHERE "+funcvp_name11+" "+vp_name11+" "+director_name11+" "+thirdline_name11+" "+ secondline_name11+""+directreport_name11;
arraylistofEmployeeDetails = new ArrayList<String>();
try {
resultSet = st.executeQuery(myQuery11);
while (resultSet.next())
{
String SERIAL_NUM = resultSet.getString("SERIAL_NUM");
if(SERIAL_NUM == null){SERIAL_NUM="";}
if (SERIAL_NUM.length() > 40){SERIAL_NUM = "Too Long";}
arraylistofEmployeeDetails.add(SERIAL_NUM);
System.out.println(SERIAL_NUM+"\n");
}
if(! (arraylistofEmployeeDetails.isEmpty())){
writeEmployeeDetailsToJsonFile(arraylistofEmployeeDetails);
}
} catch (SQLException e) {
e.printStackTrace();
StringWriter wtr = new StringWriter();
PrintWriter pwtr = new PrintWriter(wtr);
e.printStackTrace(pwtr);
String stackTrace = wtr.toString();
error_logs.append("from getDataFromEMPHCForEmployeeDetails()----- "+stackTrace+"\n");
}
}
I had similar problem with CharConversionException on DB2 jdbc driver with 1.8 Oracle Java with same error code, once updated to a never version it worked fine.
I downloaded db2jcc_license_cu and db2jcc.jar from these links.
Maybe it is worth of trying.
Try adding a JVM parameter -Ddb2.jcc.charsetDecoderEncoder=3, it solved the issue for me.
After setting the parameter db2.jcc.charsetDecoderEncoder=3, an exception will not be thrown when a non-UTF8 character is encountered but rather it will be substituted by its equivalent Unicode replacement character.
See the IBM Support article for more details https://www.ibm.com/support/pages/sqlexception-message-caught-javaiocharconversionexception-and-errorcode-4220

When i tried running this code it causes " Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 0" this exception

import javax.speech.*;
import java.util.*;// creates a default Systhesize
import javax.speech.synthesis.*; //code for text-speech engine
public class SpeechUtils
{
String speaktext;
public void dospeak(String speak,String voicename)
{
speaktext=speak;
String voiceName =voicename;
try
{
SynthesizerModeDesc desc = new
SynthesizerModeDesc(null,"general",Locale.US,null,null);
Synthesizer synthesizer = Central.createSynthesizer(desc);
synthesizer.allocate();
synthesizer.resume();
desc = (SynthesizerModeDesc)
synthesizer.getEngineModeDesc();
Voice[] voices = desc.getVoices();
Voice voice = null;
for (int i = 0; i < voices.length; i++)
{
if (voices[i].getName().equals(voiceName))
{
voice = voices[i];
break;
}
}
synthesizer.getSynthesizerProperties().setVoice(voice);
synthesizer.speakPlainText(speaktext, null);
synthesizer.waitEngineState(Synthesizer.QUEUE_EMPTY);
synthesizer.deallocate();
}catch (Exception e)
{
String message = " missing speech.properties in " + System.getProperty("user.home") + "\n";
System.out.println(""+e);
System.out.println(message);}
}
public static void main(String[] args)
{
SpeechUtils obj=new SpeechUtils();
obj.dospeak(args[0],"life is beautiful");//getting an exception here....
}
}
How to fix this exception? i am getting an error like
"Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 0
at SpeechUtils.main(SpeechUtils.java:44)".
It is a Java program or text to speech conversion.i imported all the necessary libraries.But unable to fix this exception alone
You need to provide a runtime argument while running the program. As in your code your accessing the first argument:
obj.dospeak(args[0],"life is beautiful");//getting an exception here....
If you don't provide an argument then there will be no element at index 0 of args array and hence accessing it using args[0] will throw ArrayIndexOutOfBoundsException. You need to run your code like this:
java SpeechUtils argument
replace argument with the actual value you want to input to your program
You need to pass some argument when you do call to your program from commandline
java SpeechUtils "I am doing well"
please remember
java.lang.ArrayIndexOutOfBoundsException:10
means that Array which you are trying to access does not have any element assigned to it at Array[10]
i.e. 11th element is missing. Here you are getting exception at 0 which means 0th element is not there
Missing argument While execution of the program.
"Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 0
Error caused due to missing argument which you need to provide, since you had used args[0] in the code obj.dospeak(args[0],"life is beautiful"); So pass argument while runtime. args[0] denote array with its first element so, only one argument is necessary to run your program.
Use the command java SpeechUtils YourArgumentYouWantToAdd

Categories