Support Questions

Find answers, ask questions, and share your expertise

Processor to run java code / jar file in apache nifi

avatar
Contributor

Greetings Community ,

I am aware of executeScript processor and InvokeScriptedProcessor where we can run python , ruby and groovy type code but I am looking for a processor where I can run java code with additional functionality to add external jars as well.

I found that ExecuteStreamCommand processor can be used but did not find any examples or ways to run java using that.

Can anyone direct me to examples / templates where a java code or jar is executed .

1 ACCEPTED SOLUTION

avatar
Contributor

Yes , I figured out how to run a jar in nifi using ExectureStreamCommand processor.

I am having a piece of java code , along with a jar file , by creating manifest file . I created another Master Jar file , which need to be run in nifi environment to get data. refer :- http://stackoverflow.com/questions/8890747/creating-a-jar-file-which-contains-other-library-files http://stackoverflow.com/questions/1082580/how-to-build-jars-from-intellij-properly Now once we have our JAR ready , we just need to give java -jar <jarfilename>.jar conventionally . In NIFI , we need to use ExectureStreamCommand processor . to trigger the action , step 1) create a GenerateFlowFile 2) In ExectureStreamCommand processor , update the properties as follows. ( here my jar name is engagement_3.jar) and we all know that the command to run java jar is java -jar <jarfilename>.jar but we need to omit "java" and give rest of command , but the delimiter is ";" . So the command is -jar;engagement_3.jar or -jar;<jarfilename>.jar In COMMAND PATH, specify the system environment path , <JAVA_HOME>\bin\java BUT NOT <JAVA_HOME>\bin\java.exe.

Working directory is the location where your jar is hosted in local.

Rest of the properties within ExectureStreamCommand processor are as follows.

11134-mallesh.png

View solution in original post

6 REPLIES 6

avatar
Master Guru

For Java you need to build a custom processor and package it in a NAR. There is a Maven archetype to generate the proper project structure: https://cwiki.apache.org/confluence/display/NIFI/Maven+Projects+for+Extensions

The JARs you need would be dependencies of your processors project listed in the pom.xml

Then you deploy the NAR file to the lib directory of NiFi and restart.

avatar
Master Guru

Groovy syntax is very similar to Java, and using the Module Directory property of ExecuteScript or InvokeScriptedProcessor, you could include your Java code / JARs and use Groovy only to pass on data/objects to your Java code (i.e. you wouldn't need to write everything in Groovy, just enough to call your Java class(es)).

ExecuteStreamCommand is akin to calling something from the command line, so if you can run your code from the command line using the "java" program, you can do the same from ExecuteStreamCommand.

If you can describe your code/project and its entry points, I can help get you going with ExecuteScript and Groovy if you like.

avatar

Hi @Matt Burgess

I'm relatively new to NiFi.

As of now i have parsed a hl7 file using ExtractHL7Attributes and extracted required attributes using AttributesToJSON processor. From here i want to convert it into FHIR format with the use of attributes and its values from AttributesToJSON. The attributes from AttributesToJSON will look something like this,

{"PID.PatientName.FamilyName":"Patient","PID.PatientName.GivenName":"Test", etc. }

I've a java class like to convert it into FHIR format,

package routines;

import org.hl7.fhir.dstu3.model.Patient; import org.hl7.fhir.dstu3.model.Identifier; import ca.uhn.fhir.context.FhirContext; import org.hl7.fhir.dstu3.model.ContactPoint.ContactPointSystem; import org.hl7.fhir.dstu3.model.ContactPoint.ContactPointUse; import org.hl7.fhir.dstu3.model.Reference;

public class MapFhirPatient {

public static String getFhirPatient(String firstName, String lastName, String middleName, String phoneHome, String phoneWork)

{

String result = "";

try{ Patient testPatient = new Patient();

Reference reference = new Reference();

reference.setDisplay("HealthCare Org");

testPatient.addIdentifier().setUse(Identifier.IdentifierUse.OFFICIAL).setSystem("urn:fake:mrns").setValue("800001").setAssigner(reference);

testPatient.addName().setFamily(lastName).addGiven(firstName).addGiven(middleName);

if(phoneHome != null) { testPatient.addTelecom().setSystem(ContactPointSystem.PHONE).setUse(ContactPointUse.HOME).setValue(phoneHome); }

if(phoneWork != null) { testPatient.addTelecom().setSystem(ContactPointSystem.PHONE).setUse(ContactPointUse.WORK).setValue(phoneWork); }

FhirContext context = FhirContext.forDstu3();

result = context.newJsonParser().encodeResourceToString(testPatient);

}

catch(Exception e){ result = "Error occured in mapping."; }

return result;

} }

How can i execute this code using the Module Directory property of ExecuteScript or InvokeScriptedProcessor by passing necessary parameters. And how can i get the returned data from java class and store it in a text file.

similar question raised by me to format JSON data - https://community.hortonworks.com/questions/138833/need-to-format-values-fromin-attributestojson-pro...

The end result will look something like this, which is FHIR standard for patient details.

{"resourceType":"Patient","identifier":[{"use":"official","system":"urn:fake:mrns","value":"800001","assigner":{"display":"HealthCare Org"}}],"name":[{"family":"Patient","given":"Test12"}],"telecom":[{"system":"phone","value":"111-111-1111","use":"home"}]}

avatar

hi,

grovy code below to get flow file:-


attrMap = ['myAttr1': '1', 'myAttr2': Integer.toString(2)]
flowFile = session.get()
if(!flowFile) return
flowFile = session.putAllAttributes(flowFile, attrMap)

grovy code below to run java jar

def command = "java -jar UpdateAppIdXMLRequest.jar file.xml" 
def process = command.execute()
process.waitFor()
def output = process.in.text
log.info output

my question is how to pass flow file to java jar command. Shall i deserilized to disk and pass as file to java command as input file?

avatar
Contributor

Yes , I figured out how to run a jar in nifi using ExectureStreamCommand processor.

I am having a piece of java code , along with a jar file , by creating manifest file . I created another Master Jar file , which need to be run in nifi environment to get data. refer :- http://stackoverflow.com/questions/8890747/creating-a-jar-file-which-contains-other-library-files http://stackoverflow.com/questions/1082580/how-to-build-jars-from-intellij-properly Now once we have our JAR ready , we just need to give java -jar <jarfilename>.jar conventionally . In NIFI , we need to use ExectureStreamCommand processor . to trigger the action , step 1) create a GenerateFlowFile 2) In ExectureStreamCommand processor , update the properties as follows. ( here my jar name is engagement_3.jar) and we all know that the command to run java jar is java -jar <jarfilename>.jar but we need to omit "java" and give rest of command , but the delimiter is ";" . So the command is -jar;engagement_3.jar or -jar;<jarfilename>.jar In COMMAND PATH, specify the system environment path , <JAVA_HOME>\bin\java BUT NOT <JAVA_HOME>\bin\java.exe.

Working directory is the location where your jar is hosted in local.

Rest of the properties within ExectureStreamCommand processor are as follows.

11134-mallesh.png

avatar
New Contributor

Hello Team, I am facing some problem while running JAR file from NIFI. please find below screenshot for same

abhiCoder_0-1638161470940.png

could anyone help for same?