Issue
I'm developing a very simple Asterisk-Java IVR based program that greets the caller, retrieves some information from a web service, reads up the retrieved data to the caller, and finally hangs up.
What steps I followed:
Added the following line is entered on extensions_custom.conf:
exten => 1000,n,Agi(agi://192.168.0.8/ivryobi.agi)
Created the following file structure inside C:\Project\target\classes\
Runnable.java
IvrYobi.java
Runnable.class
IvrYobi.class
fastagi-mapping.properties
Inside fastagi-mapping.properties I have:
ivryobi.agi = main.IvrYobi
The contens of IvrYoby are:
public class IvrYobi extends BaseAgiScript {
public void service(AgiRequest request, AgiChannel channel) throws AgiException {
String callerMsisdn = request.getCallerIdNumber();
}
When it works normally
Running the following command in the console
C:\Project\target\classes>java -cp asterisk-java.jar;commons-lang3-3.10.jar;commons-logging-1.2.jar;httpclient-4.5.12.jar;httpcore-4.4.13.jar;mysql-connector-java-8.0.20.jar;. org.asteriskjava.fastagi.DefaultAgiServer
As you can see on the following console output, works perfectly
jun 30, 2020 6:09:04 PM org.asteriskjava.fastagi.DefaultAgiServer startup INFORMACIËN: Listening on *:4573. jun 30, 2020 6:09:09 PM org.asteriskjava.fastagi.AbstractAgiServer getPool INFORMACIËN: Thread pool started. jun 30, 2020 6:09:09 PM org.asteriskjava.fastagi.ResourceBundleMappingStrategy loadResourceBundle INFORMACIËN: Added mapping for 'ivryobi.agi' to class IvrYobi ...
When the problem appears
When I run the very same code, but insted of the console I use Runnable.java
Here are the contents of Runnable.java:
DefaultAgiServer server = new DefaultAgiServer();
public MyRunnable() {
ClassNameMappingStrategy strategy = new ClassNameMappingStrategy(false);
server.setMappingStrategy(strategy);
}
public void run() {
try {
server.startup();
} catch (IllegalStateException | IOException e) {
e.printStackTrace();
server.shutdown();
}
}
public void stop() {
server.shutdown();
}
We can observe the following error on Eclipse's console:
0 [main] DEBUG org.asteriskjava.fastagi.DefaultAgiServer - Using channelFactory org.asteriskjava.fastagi.internal.DefaultAgiChannelFactory 9 [main] INFO org.asteriskjava.fastagi.DefaultAgiServer - Listening on *:4573. 4806 [main] DEBUG org.asteriskjava.fastagi.DefaultAgiServer - Received connection from /192.168.0.254 4810 [main] INFO org.asteriskjava.fastagi.DefaultAgiServer - Thread pool started. 4849 [AJ DaemonPool-1.1] DEBUG org.asteriskjava.fastagi.ClassNameMappingStrategy - Unable to create AgiScript instance of type ivryobi.agi: Class not found, make sure the class exists and is available on the CLASSPATH 4849 [AJ DaemonPool-1.1] ERROR org.asteriskjava.fastagi.internal.FastAgiConnectionHandler - No script configured for URL 'agi://192.168.0.8/ivryobi.agi' (script 'ivryobi.agi')
Attempted troubleshooting
- I already made sure that fastagi-mapping.properties is on the CLASSPATH.
- Tried different name and case
- Copied the .properties file on the java Execution Path
- Compiled the project as an executable jar
- Added / removed packages inside eclipse (ex: com.test.IvrYobi) and also applied the changes on the .properties file.
- I checked the code inside asterisk-java-3.5.0.jar, looks like that in case that the configuration file is not found, it just continues without throwing any warning. Since is packed inside the jar I'm unable to modify that code.
Please, do you have any other ideas I can try?
Solution
Finally found the solution by myself
I had to recompile asterisk-java.jar using the project's source code
On DefaultAgiServer.java change the line:
resourceBundle = ResourceBundle.getBundle(configResourceBundleName);
With:
FileInputStream fis = new FileInputStream("myivr.properties");
resourceBundle = new PropertyResourceBundle(fis);
logger.info("resourceBundle cargado ok!");
On the catch, replace the
return;
with a more decent response, so you will know if the resource could not be loaded
logger.info("resourceBundle cargado ok!");
}
catch (MissingResourceException | IOException e)
{
logger.error("No existe el recurso invocado: " + e.getMessage());
return;
}
Answered By - Felipe La Rotta
Answer Checked By - David Goodson (JavaFixing Volunteer)