How do you tell the reference path when loading a class? - java

I'm trying to use JavaLoader to load a java (HttpAsyncClient) class into ColdFusion.
client = loader.create("org.apache.commons.HttpAsyncClient")
How do we know the reference that is org.apache.commons.HttpAsyncClient? I thought if you open the jar file and follow the directory structure, it will give you the reference path. But I don't think this is true.
I'm trying to use the HttpAsyncClient but I'm unable to load it:
client = loader.create("org.apache.commons.HttpAsyncClient") returns a class not found error.
Loader is a reference to JavaLoader, which loads Java classes into your CF server.

Rather than reinvent the wheel, why not try an existing tool like Mark Mandel's AsyncHTTP library?
Update: From the comments, that tool is ACF only. So you might try using the concrete class DefaultHttpAsyncClient as shown in the Asynchronous HTTP Exchange example.

I don't know ColdFusion. You probably have to specify the full path to the class, not just the package containing the class.
According to an example I found the full package and class name is this: org.apache.http.nio.client.HttpAsyncClient
You can also use the javadoc to find out the package and class names: http://hc.apache.org/httpcomponents-client-ga/httpclient/apidocs/index.html
Getting something async going with an interface like this will probably be brutal. I would suggest trying the sync version first.
EDIT
I would try adapting this sync example to CF: http://hc.apache.org/httpcomponents-client-ga/httpclient/examples/org/apache/http/examples/client/ClientWithResponseHandler.java
When you instantiate HttpGet you have to pass extra parameters to init() as they do in this example: http://www.coldfusionjedi.com/index.cfm/2009/5/29/Generating-Speech-with-ColdFusion-and-Java

Related

Create custom gradle plugin to analyze java source code and generate codes

I am trying to create a plugin to generate some java code and write back to the main source module. I was able to create a some simple pojo class using JavaPoet and write to the src/main/java.
To make this useful, it should read the code from src/maim/java folder and analyze the classes using reflection. Look for some annotation then generate some codes. Do I use the SourceTask for this case. Looked like I can only access the classes by the files. Is that possible to read the java classes as the class and using reflection analyze the class?
Since you specified what you want to do:
You'll need to implement an annotation processor. This has absolutely nothing to do with gradle, and a gradle plugin is actually the wrong way to go about this. Please look into Java Annotation Processor and come back with more questions if any come up.
With JavaForger you can read input classes and generate sourcecode based on that. It also provides an API to insert it into existing classes or create new classes based on the input file. In contrast to JavaPoet, JavaForger has a clear separation between code to be generated and settings on where and how to insert it. An example of a template for a pojo can look like this:
public class ${class.name}Data {
<#list fields as field>
private ${field.type} ${field.name};
</#list>
<#list fields as field>
public ${field.type} ${field.getter}() {
return ${field.name};
}
public void ${field.setter}(${field.type} ${field.name}) {
this.${field.name} = ${field.name};
}
</#list>
}
The example below uses a template called "myTemplate.javat" and adds some extra settings like creating the file if it does not exist and changing the path where the file will be created from */path/* to */pathToDto/*. The the path to the input class is given to read the class name and fields and more.
JavaForgerConfiguration config = JavaForgerConfiguration.builder()
.withTemplate("myTemplate.javat")
.withCreateFileIfNotExists(true)
.withMergeClassProvider(ClassProvider.fromInputClass(s -> s.replace("path", "pathToPojo")))
.build();
JavaForger.execute(config, "MyProject/path/inputFile.java");
If you are looking for a framework that allows changing the code more programatticaly you can also look at JavaParser. With this framework you can construct an abstract syntax tree from a java class and make changes to it.

How to subclass SubethaSmtp SMTPClient class

I am trying to develop a simple SMTPclient for testing purposes using the SubethaSmtp client package. i want to use the SMTPClient class instead of the SmartClient class for more control but i have not been able to figure out how to write mail data using SMTPClient, the only OutputStream exposed to public or external subclasses is the one for sending commands, the ones for sending data (after sending the DATA command) is exposed only to classes in the same package (SmartClient).
am i missing something here? i would like to know how a direct subclass of SMARTClient can written to work around this problem.
Looks like you are correct, you cannot simply extend the SMTPClient and get access similar to the one that SmartClient has, being a same-package class.
At this point you can either:
1) Fork your own version of the app from https://github.com/voodoodyne/subethasmtp and do whatever the hell you like with it, or
2) Go all the way and implement your own version of SMTPClient, as the package protected SMTPClient.dotTerminatedOutput;, used by SmartClient.dataWrite() actually is just instantiated like so
...
this.rawOutput = this.socket.getOutputStream();
this.dotTerminatedOutput = new DotTerminatedOutputStream(this.rawOutput);
...

Reflections library returns empty list in Android

I'm attempting to retrieve a list of classes with a specific annotation in Android. I'm trying to use the Reflections library to do so. But no matter what I do, Reflections returns an empty set. Finally, I tried using Reflections.getAllTypes(), which should return all classes in a package, and it gives me the message "Couldn't find subtypes of Object. Make sure SubTypesScanner initialized to include Object class - new SubTypesScanner(false)" I have verified that I am doing so, so I looked in the code for that method and it returns that error if there are no classes in the package.
Here's an example of the code where I'm getting the error:
Reflections reflections = new Reflections(this.getClass().getPackage().getName(),
new SubTypesScanner(false));
Set<String> classes = reflections.getAllTypes(); // Throws runtime error
This should, at the very least, return the class that it is called from. I've also tried using an empty string for the package, and the answer here. Any ideas what could be causing this?
I met the same problem. Since Reflections use java assist to resolve .class file in .jar file, which isn't exist in android application, so it is not possible to use Reflections. However we could use other tool to resolve .dex and it would work

POI for XPages - using xwpfdocument

To help solve another problem I have, I'm testing the following code in the postGenerationProcess event of the POI Word widget:
var jce:writeXWPFDocument = new writeXWPFDocument();
var newString3 = jce.doSomething3(xwpfdocument);
print("newString3 = " + newString3);
doSomething3 is defined in a Java class contained in the .nsf.
public class writeXWPFDocument {
public String doSomething3(XWPFDocument xwpfdocument) {
return "DO SOMETHING - xwpfdocument";
}}
When I run this code, I get the error:
Java method 'doSomething3(org.apache.poi.xwpf.usermodel.XWPFDocument)'
on java class 'AZGPackage.writeXWPFDocument' not found
What could be causing this error?
#Knut Hermann - this is a test which relates to the other problem you have been helping me with.
Edit to make the correct answer easier to find:
I have used poi in a few applications. I've encountered similar problems twice: First, usually when I accidentally import a class with the same name from the wrong package (like lotus.local.domino.Database instead of lotus.domino.Database). The other time I encountered this (and the only time the package name was identical) was when I had poi in a plug-in that I had added to the build path and also had it installed by a poi extension library I had built. If you can't cast an object as itself, there is an issue with the ClassLoader, and I don't know what would cause that other than a class being listed twice.
SSJS seems to pass a different object type to the function. Try to change the class of the parameter to Object and for testing return the class name.
In a production code you could check with instanceof if the parameter has the right data type.
In General: consider using a facade pattern, so you keep your complex Java classes away from SSJS

How to implement dynamic referenced configuration in Java?

I have a configuration (config.properties) something like
app.rootDir=
app.reportDir=${app.rootDir}/report
The app.rootDir is not a fixed parameter and it must be initialized by external module. I need keep the ${app.reportDir} keep dynamic reference to ${app.rootDir}.
Use pseudo code to illustrate the problem:
// Init the root dir as '/usr/app'
config.setValue('app.rootDir','/usr/app');
// I need the reportDir to be '/usr/app/report'
String reportDir = config.getValue('app.reportDir');
I can write some codes to get this feature but I'd like to know if there is any existing library do this?
I can use properties, yaml, or json as configuration file type, according to the library availability.

Categories

Resources