Fop Factory Run time exception - apache-fop

i am trying to execute the following code
import java.io.File;
import java.io.OutputStream;
//JAXP
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.Source;
import javax.xml.transform.Result;
import javax.xml.transform.stream.StreamSource;
import javax.xml.transform.sax.SAXResult;
//FOP
import org.apache.fop.apps.FOUserAgent;
import org.apache.fop.apps.Fop;
import org.apache.fop.apps.FopFactory;
import org.apache.fop.apps.MimeConstants;
/**
* This class demonstrates the conversion of an XML file to PDF using * JAXP (XSLT) and FOP (XSL-FO).
*/
public class xml2pd {
/**
* Main method.
* #param args command-line arguments
*/
public static void main(String[] args) {
try {
System.out.println("FOP ExampleXML2PDF\n");
System.out.println("Preparing...");
// Setup directories
File baseDir = new File("e:");
File outDir = new File(baseDir, "out");
outDir.mkdirs();
// Setup input and output files
File xmlfile = new File(baseDir, "ajay.xml");
File xsltfile = new File(baseDir, "test.xsl");
File pdffile = new File(outDir, "ResultXML2PDF.pdf");
System.out.println("Input: XML (" + xmlfile + ")");
System.out.println("Stylesheet: " + xsltfile);
System.out.println("Output: PDF (" + pdffile + ")");
System.out.println();
System.out.println("Transforming...");
// configure fopFactory as desired
**strong text**FopFactory fopFactory = FopFactory.newInstance();
FOUserAgent foUserAgent = fopFactory.newFOUserAgent();
// configure foUserAgent as desired
// Setup output
OutputStream out = new java.io.FileOutputStream(pdffile);
out = new java.io.BufferedOutputStream(out);
try {
// Construct fop with desired output format
Fop fop = fopFactory.newFop(MimeConstants.MIME_PDF, foUserAgent, out);
System.out.println("After MIME_PDF");
// Setup XSLT
TransformerFactory factory = TransformerFactory.newInstance();
Transformer transformer = factory.newTransformer(new StreamSource(xsltfile));
// Set the value of a <param> in the stylesheet
transformer.setParameter("versionParam", "2.0");
// Setup input for XSLT transformation
Source src = new StreamSource(xmlfile);
// Resulting SAX events (the generated FO) must be piped through to FOP
Result res = new SAXResult(fop.getDefaultHandler());
// Start XSLT transformation and FOP processing
transformer.transform(src, res);
} finally {
out.close();
}
System.out.println("Success!");
} catch (Exception e) {
e.printStackTrace(System.err);
System.exit(-1);
}
}
}
(this is an example copied from http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/examples/embedding/java/embedding/ExampleXML2PDF.java?view=markup) but i am getting the following runtime error...
Exception in thread "main" java.lang.NoClassDefFoundError: org/apache/commons/logging/LogFactory
at org.apache.fop.apps.FopFactory.<clinit>(FopFactory.java:65)
at ExampleFO2PDF.<init>(ExampleFO2PDF.java:33)
at ExampleFO2PDF.main(ExampleFO2PDF.java:116)
Caused by: java.lang.ClassNotFoundException: org.apache.commons.logging.LogFactory
at java.net.URLClassLoader$1.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(Unknown Source)
at java.lang.ClassLoader.loadClass(Unknown Source)
at sun.misc.Launcher$AppClassLoader.loadClass(Unknown Source)
at java.lang.ClassLoader.loadClass(Unknown Source)
... 3 more
can anybody help me to resolve this...?
thanks in advance.

You need commons-logging package (e.g. commons-logging-1.0.4.jar). To do this, just download and put it in your classpath.

Related

Unable to run the script written to test the Play store app

I am new to Appium and want to work on it. As a beginner I am trying to test the Play store application for which I have written the script in eclipse. I am trying to open the app and then click on the text box to write some text. When I am running the script, its only initiating the application and then nothing happens. Please find the code below.
package tests;
import java.net.MalformedURLException;
import java.net.URL;
import org.openqa.selenium.By;
import org.openqa.selenium.remote.DesiredCapabilities;
import io.appium.java_client.AppiumDriver;
import io.appium.java_client.MobileElement;
import io.appium.java_client.android.AndroidDriver;
public class AppiumTest {
public static void main(String[]args){
AppiumDriver<MobileElement> driver = null;
//Set the Desired Capabilities
DesiredCapabilities caps = new DesiredCapabilities();
caps.setCapability("deviceName", "Vinee");
caps.setCapability("udid", "3204d6dea76f219d");
caps.setCapability("platformName", "Android");
caps.setCapability("platformVersion", "5.1.1");
caps.setCapability("appPackage", "com.android.vending");
caps.setCapability("appActivity", "com.google.android.finsky.activities.MainActivity");
caps.setCapability("noReset", "true");
//Instantiate Appium Driver
try
{
driver = new AndroidDriver<MobileElement>(new URL("http://0.0.0.0:4723/wd/hub"),caps);
}
catch (MalformedURLException e)
{
System.out.println(e.getMessage());
}
//Find Google Play element using ID property and click on it
driver.findElement(By.id("com.android.vending:id/search_box_idle_text")).sendKeys("Calculator");
}
}
The error message I am getting is :
Jul 24, 2018 10:03:12 AM io.appium.java_client.remote.AppiumCommandExecutor$1 lambda$0
INFO: Detected dialect: W3C
Exception in thread "main" java.lang.NoClassDefFoundError: org/apache/commons/lang3/StringUtils
at io.appium.java_client.HasSessionDetails.lambda$0(HasSessionDetails.java:49)
at java.util.stream.ReferencePipeline$2$1.accept(Unknown Source)
at com.google.common.collect.CollectSpliterators$1.lambda$forEachRemaining$1(CollectSpliterators.java:117)
at java.util.Iterator.forEachRemaining(Unknown Source)
at java.util.Spliterators$IteratorSpliterator.forEachRemaining(Unknown Source)
at com.google.common.collect.CollectSpliterators$1.forEachRemaining(CollectSpliterators.java:117)
at java.util.stream.AbstractPipeline.copyInto(Unknown Source)
at java.util.stream.AbstractPipeline.wrapAndCopyInto(Unknown Source)
at java.util.stream.ReduceOps$ReduceOp.evaluateSequential(Unknown Source)
at java.util.stream.AbstractPipeline.evaluate(Unknown Source)
at java.util.stream.ReferencePipeline.collect(Unknown Source)
at io.appium.java_client.HasSessionDetails.getSessionDetails(HasSessionDetails.java:52)
at io.appium.java_client.HasSessionDetails.getSessionDetail(HasSessionDetails.java:56)
at io.appium.java_client.HasSessionDetails.getPlatformName(HasSessionDetails.java:65)
at io.appium.java_client.internal.JsonToMobileElementConverter.<init>(JsonToMobileElementConverter.java:49)
at io.appium.java_client.AppiumDriver.<init>(AppiumDriver.java:89)
at io.appium.java_client.AppiumDriver.<init>(AppiumDriver.java:94)
at io.appium.java_client.android.AndroidDriver.<init>(AndroidDriver.java:93)
at tests.AppiumTest.main(AppiumTest.java:32)
Caused by: java.lang.ClassNotFoundException: org.apache.commons.lang3.StringUtils
at java.net.URLClassLoader.findClass(Unknown Source)
at java.lang.ClassLoader.loadClass(Unknown Source)
at sun.misc.Launcher$AppClassLoader.loadClass(Unknown Source)
at java.lang.ClassLoader.loadClass(Unknown Source)
... 19 more
Please let me know how to proceed here after.
You can add the jar file containing the org/apache/commons/lang3/StringUtils at http://commons.apache.org/proper/commons-lang/download_lang.cgi.
Download the commons-lang3-3.7-src.zip under source and add to the project.

Cannot send request to MQSeries service

Im trying to send request with such code
import com.ibm.mq.jms.*;
import com.ibm.msg.client.wmq.WMQConstants;
import javax.jms.Session;
import javax.jms.TextMessage;
public class MQSend {
public static void main(String[] args)
{
try {
MQQueueConnectionFactory cf = new MQQueueConnectionFactory();
cf.setHostName("blabla");
cf.setPort(15000);
cf.setIntProperty(WMQConstants.WMQ_CONNECTION_MODE, WMQConstants.WMQ_CM_CLIENT);
cf.setQueueManager("");
cf.setChannel("blabla");
MQQueueConnection connection = (MQQueueConnection) cf.createQueueConnection("blabla","blabla");
MQQueueSession session = (MQQueueSession) connection.createQueueSession(false, Session.AUTO_ACKNOWLEDGE);
MQQueue queue = (MQQueue) session.createQueue("blabla");
MQQueueSender sender = (MQQueueSender) session.createSender(queue);
long uniqueNumber = System.currentTimeMillis() % 1000;
TextMessage message = (TextMessage) session.createTextMessage("Basic Queue Test "+ uniqueNumber);
// Start the connection
connection.start();
// sender.send(message);
System.out.println("Sent message to Queue MyTestQueue: " + message.getText());
// sender.close();
session.close();
connection.close();
System.out.println("Message Sent OK.\n");
}
catch (Exception ex) {
System.out.println(ex);
System.out.println("Message Send Failure\n");
}
}
}
I got
Exception in thread "main" java.lang.NoClassDefFoundError: com/ibm/msg/client/commonservices/trace/Trace
at com.ibm.msg.client.jms.internal.JmsReadablePropertyContextImpl.<clinit>(JmsReadablePropertyContextImpl.java:51)
at com.hsbc.hbfr.test.automation.tools.jrb.plugins.itm.MQSend.main(MQSend.java:14)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:497)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:147)
Caused by: java.lang.ClassNotFoundException: com.ibm.msg.client.commonservices.trace.Trace
So issue is that java can't get appropriate jar for com/ibm/msg/client/commonservices/trace/Trace
But I even don't use such dependency in code, any suggestions?
thanks
Did you install MQ Client on the server? Did you put ALL of the MQ jar files in the CLASSPATH as per the docs? Looks like you missed at least one.

Talend - The import org.apache cannot be resolved

I've created a custom Talend component, which at certain step connects to an external Http service. For that, I'm using org.apache.commons.httpclient through javajet imports. I've seen the modules already exist in the Modules view. Nevertheless, when running a job the console outputs:
Execution failed : Failed to generate code.
[----------
1. ERROR in /Users/frb/Downloads/TOS_DI-20160510_1709-V6.2.0/workspace/.JETEmitters/src/org/talend/designer/codegen/translators/ngsi/orion/TOrionAppendBeginJava.java (at line 14)
import org.apache.commons.httpclient.*;
^^^^^^^^^^
The import org.apache cannot be resolved
----------
2. ERROR in /Users/frb/Downloads/TOS_DI-20160510_1709-V6.2.0/workspace/.JETEmitters/src/org/talend/designer/codegen/translators/ngsi/orion/TOrionAppendBeginJava.java (at line 15)
import org.apache.commons.httpclient.methods.*;
^^^^^^^^^^
The import org.apache cannot be resolved
----------
3. ERROR in /Users/frb/Downloads/TOS_DI-20160510_1709-V6.2.0/workspace/.JETEmitters/src/org/talend/designer/codegen/translators/ngsi/orion/TOrionAppendBeginJava.java (at line 16)
import org.apache.commons.httpclient.params.HttpMethodParams;;
^^^^^^^^^^
The import org.apache cannot be resolved
----------
3 problems (3 errors)
]
Any hints about how to fix this issue? My Talend version is 6.2.0.
EDIT 1
This is my begin code:
<%# jet
imports="
org.talend.core.model.process.INode
org.talend.core.model.process.ElementParameterParser
org.talend.core.model.metadata.IMetadataTable
org.talend.core.model.metadata.IMetadataColumn
org.talend.core.model.process.IConnection
org.talend.core.model.process.IConnectionCategory
org.talend.designer.codegen.config.CodeGeneratorArgument
org.talend.core.model.metadata.types.JavaTypesManager
org.talend.core.model.metadata.types.JavaType
java.util.List
java.util.Map
org.apache.commons.httpclient.*
org.apache.commons.httpclient.methods.*
org.apache.commons.httpclient.params.HttpMethodParams
"
%>
<%
// Get the CID
CodeGeneratorArgument codeGenArgument = (CodeGeneratorArgument) argument;
INode node = (INode)codeGenArgument.getArgument();
String cid = node.getUniqueName();
// Get the component parameters
String orionEndpoint = ElementParameterParser.getValue(node, "__ORION_ENDPOINT__");
String authEndpoint = ElementParameterParser.getValue(node, "__AUTH_ENDPOINT__");
String authUsername = ElementParameterParser.getValue(node, "__AUTH_USERNAME__");
String authPassword = ElementParameterParser.getValue(node, "__AUTH_PASSWORD__");
String entityIdField = ElementParameterParser.getValue(node, "__ENTITY_ID_FIELD__");
String entityTypeField = ElementParameterParser.getValue(node, "__ENTITY_TYPE_FIELD__");
String defaultEntityType = ElementParameterParser.getValue(node, "__DEFAULT_ENTITY_TYPE__");
String ignoredFilds = ElementParameterParser.getValue(node, "__IGNORED_FIELDS__");
%>
System.out.println("I am the begin section");
HttpClient client = new HttpClient();
PostMethod method = new PostMethod(<%=authEndpoint%>);
method.setRequestHeader(new Header("Content-Type", "application/json"));
method.setRequestBody("{\"username\":\"" + <%=authUsername%> + "\",\"password\":\"" + <%=authPassword%> + "\"}");
try {
int statusCode = client.executeMethod(method);
if (statusCode != HttpStatus.SC_OK) {
System.err.println("Method failed: " + method.getStatusLine());
} // if
byte[] responseBody = method.getResponseBody();
System.out.println(new String(responseBody));
} catch (HttpException e) {
System.err.println("Fatal protocol violation: " + e.getMessage());
e.printStackTrace();
} catch (IOException e) {
System.err.println("Fatal transport error: " + e.getMessage());
e.printStackTrace();
} finally {
method.releaseConnection();
} // try
EDIT 2
I've added the following to my Component Descriptor file:
<IMPORTS>
<IMPORT
NAME="commons-httpclient"
MODULE="commons-httpclient-3.1.jar"
REQUIRED="true"
/>
</IMPORTS>
Now, in the modules view I'm able to see the following:
Sadly, the component outputs the same errors.
EDIT 3
After removing the imports and using fully qualified names, as suggested by #Balazs Gunics, the code seems to be generated. Nevertheless, some other errors related to commons-httpclient arise at running time:
Starting job job_tOrionAppend at 08:20 21/06/2016.
[statistics] connecting to socket on port 3916
[statistics] connected
I am the begin section
Exception in thread "main" java.lang.NoClassDefFoundError: org/apache/commons/logging/LogFactory
at org.apache.commons.httpclient.HttpClient.<clinit>(HttpClient.java:66)
at iotp_talend_connectors.job_torionappend_0_1.job_tOrionAppend.tMysqlInput_1Process(job_tOrionAppend.java:854)
at iotp_talend_connectors.job_torionappend_0_1.job_tOrionAppend.tMysqlConnection_1Process(job_tOrionAppend.java:422)
at iotp_talend_connectors.job_torionappend_0_1.job_tOrionAppend.runJobInTOS(job_tOrionAppend.java:1355)
at iotp_talend_connectors.job_torionappend_0_1.job_tOrionAppend.main(job_tOrionAppend.java:1212)
Caused by: java.lang.ClassNotFoundException: org.apache.commons.logging.LogFactory
at java.net.URLClassLoader$1.run(URLClassLoader.java:372)
at java.net.URLClassLoader$1.run(URLClassLoader.java:361)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(URLClassLoader.java:360)
at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:308)
[statistics] disconnected
[statistics] disconnected
at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
... 5 more
Job job_tOrionAppend ended at 08:20 21/06/2016. [exit code=1]
So in the begin.javajet code of yours the following code will only import these libraries for the code generation itself. But you need them to the generated code.
Generating java using java makes it hard to oversee this.
<%# jet
imports="
org.apache.commons.httpclient.*
org.apache.commons.httpclient.methods.*
org.apache.commons.httpclient.params.HttpMethodParams
So what you need is to have these imports added to the generated code. Well that is not really possible :( https://www.talendforge.org/forum/viewtopic.php?id=3670 To do that you need to modify the xml descriptor for your component.
So your imports are right. All you have to do is make sure you use the fully qualified names. I.e.: This piece of code:
System.out.println("I am the begin section");
HttpClient client = new HttpClient();
PostMethod method = new PostMethod(<%=authEndpoint%>);
Have to be rewritten to look like this:
System.out.println("I am the begin section");
org.apache.commons.httpclient.HttpClient client =
new org.apache.commons.httpclient.HttpClient();
org.apache.commons.httpclient.methods.PostMethod method =
new org.apache.commons.httpclient.methods.PostMethod(<%=authEndpoint%>);
Yes, it would be way more elegant if we could import the classes and use them.

Groovy program to connect mongo db

I am trying to connect mongodb using Groovy language but i am getting error like this (which is posted below) and i have added necessary jar file.I am using mongodb verion : mongodb-driver-3.2.2.jar .
Please help me to solve this problem
Exception in thread "main" java.lang.NoClassDefFoundError: com/mongodb/operation/OperationExecutor
at java.lang.Class.getDeclaredConstructors0(Native Method)
at java.lang.Class.privateGetDeclaredConstructors(Unknown Source)
at java.lang.Class.getDeclaredConstructors(Unknown Source)
at org.codehaus.groovy.reflection.CachedClass$2$1.run(CachedClass.java:69)
at java.security.AccessController.doPrivileged(Native Method)
at org.codehaus.groovy.reflection.CachedClass$2.initValue(CachedClass.java:67)
at org.codehaus.groovy.reflection.CachedClass$2.initValue(CachedClass.java:64)
at org.codehaus.groovy.util.LazyReference.getLocked(LazyReference.java:46)
at org.codehaus.groovy.util.LazyReference.get(LazyReference.java:33)
at org.codehaus.groovy.reflection.CachedClass.getConstructors(CachedClass.java:258)
at groovy.lang.MetaClassImpl.<init>(MetaClassImpl.java:213)
at groovy.lang.MetaClassImpl.<init>(MetaClassImpl.java:223)
at groovy.lang.MetaClassRegistry$MetaClassCreationHandle.createNormalMetaClass(MetaClassRegistry.java:168)
at groovy.lang.MetaClassRegistry$MetaClassCreationHandle.createWithCustomLookup(MetaClassRegistry.java:158)
at groovy.lang.MetaClassRegistry$MetaClassCreationHandle.create(MetaClassRegistry.java:141)
at org.codehaus.groovy.reflection.ClassInfo.getMetaClassUnderLock(ClassInfo.java:209)
at org.codehaus.groovy.reflection.ClassInfo.getMetaClass(ClassInfo.java:241)
at org.codehaus.groovy.runtime.metaclass.MetaClassRegistryImpl.getMetaClass(MetaClassRegistryImpl.java:255)
at org.codehaus.groovy.runtime.InvokerHelper.getMetaClass(InvokerHelper.java:859)
at org.codehaus.groovy.runtime.callsite.CallSiteArray.createCallConstructorSite(CallSiteArray.java:84)
at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCallConstructor(CallSiteArray.java:57)
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.callConstructor(AbstractCallSite.java:182)
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.callConstructor(AbstractCallSite.java:194)
at com.sample.MongoService.client(MongoService.groovy:14)
at com.sample.MongoService.collection(MongoService.groovy:21)
at com.sample.MongoService$collection.call(Unknown Source)
at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:45)
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:108)
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:116)
at com.sample.MongoDBController.method(MongoDBController.groovy:10)
at com.sample.MongoDBController$method.call(Unknown Source)
at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:45)
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:108)
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:112)
at com.sample.GroovyDemoApp.main(GroovyDemoApp.groovy:12)
Caused by: java.lang.ClassNotFoundException: com.mongodb.operation.OperationExecutor
at java.net.URLClassLoader$1.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(Unknown Source)
at java.lang.ClassLoader.loadClass(Unknown Source)
at sun.misc.Launcher$AppClassLoader.loadClass(Unknown Source)
at java.lang.ClassLoader.loadClass(Unknown Source)
at java.lang.ClassLoader.loadClassInternal(Unknown Source)
... 35 more
Update :
This is my Groovy code. with this code i am trying to connect Mongodb
// error is in this line . i .e -
// The type com.mongodb.operation.CreateIndexesOperation cannot be resolved.
// It is indirectly referenced from required .class files )
package com.sample
import com.mongodb.*
class MongoService {
private static MongoClient mongoClient
private static host = "localhost" //your host name
private static port = 27017 //your port no.
private static databaseName = "db"
public static MongoClient client() {
if(mongoClient == null){
return new MongoClient(host,port)
}else {
return mongoClient
}
}
public DBCollection collection(collectionName) {
DB db = client().getDB(databaseName)
return db.getCollection(collectionName)
}
}
To use the MongoDB driver you can either use the JAR, or #Grab it from Maven.
Using the JAR
To use the JAR, you need to add it to Groovy's classpath. This is done with the -cp argument:
#!/usr/bin/env groovy -cp /path/to/jar/file
println 'Hello'
Using Maven
You can simply use Groovy's #Grab to take care of the dependency for you:
#Grab('org.mongodb:mongodb-driver:3.2.2')
println 'Hello'
Working example
Here's a working example based on the code you posted:
#Grab('org.mongodb:mongodb-driver:3.2.2')
import com.mongodb.MongoClient
import com.mongodb.DBCollection
import com.mongodb.DB
import com.mongodb.BasicDBObject
class MongoService {
private MongoClient mongoClient
def host = "localhost" //your host name
def port = 27017 //your port no.
def databaseName = 'test'
public MongoClient client() {
mongoClient = mongoClient ?: new MongoClient(host, port)
return mongoClient
}
public DBCollection collection(collectionName) {
DB db = client().getDB(databaseName)
return db.getCollection(collectionName)
}
}
def service = new MongoService(databaseName: 'db')
def foo = service.collection('foo')
def data = [
[firstName: 'Jane', lastName: 'Doe'],
[firstName: 'Elvis', lastName: 'Presley']
].collect { it as BasicDBObject }
foo.insert(data)
foo.find().toArray().each {
println it
}
I've never used MongoDB before, so whether my use case is useful or not is debatable.

StringTemplate : how to import from a jar?

I have a case where I am loading a string template group from a file contained in a jar.
This works fine using the following mechanism:
final String urlName = new StringBuilder()
.append("jar:file:").append(templateJar.getAbsolutePath()).append("!")
.append(templateFileName).toString();
final URL url;
try {
url = new URL(urlName);
} catch (MalformedURLException ex) {
throw new GeneratorException("bad manifest url", ex);
}
final STGroup stg = new STGroupFile(url, "US-ASCII", '<', '>');
The difficulty comes in when the template file contains an
...
import "../../dataTypeMaps.stg"
...
String template fails with the following:
can't load group file jar:file:/home/phreed/.m2/repository/edu/vanderbilt/isis/druid/druid-template/2.0.0/druid-template-2.0.0.jar!/template/src/main/java/sponsor/orm/ContractCreator.stg
Caused by: java.lang.IllegalArgumentException: No such group file: ../../dataTypeMaps.stg
at org.stringtemplate.v4.STGroupFile.<init>(STGroupFile.java:69)
at org.stringtemplate.v4.STGroup.importTemplates(STGroup.java:570)
at org.stringtemplate.v4.compiler.GroupParser.group(GroupParser.java:199)
at org.stringtemplate.v4.STGroup.loadGroupFile(STGroup.java:619)
at org.stringtemplate.v4.STGroupFile.load(STGroupFile.java:139)
at org.stringtemplate.v4.STGroupFile.load(STGroupFile.java:128)
at org.stringtemplate.v4.STGroup.lookupTemplate(STGroup.java:237)
at org.stringtemplate.v4.STGroup.getInstanceOf(STGroup.java:172)
at edu.vanderbilt.isis.druid.generator.Generator.build(Generator.java:215)
at edu.vanderbilt.isis.druid.generator.DruidMojo.execute(DruidMojo.java:193)
at org.apache.maven.plugin.DefaultBuildPluginManager.executeMojo(DefaultBuildPluginManager.java:101)
at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:209)
at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:153)
at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:145)
at org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject(LifecycleModuleBuilder.java:84)
at org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject(LifecycleModuleBuilder.java:59)
at org.apache.maven.lifecycle.internal.LifecycleStarter.singleThreadedBuild(LifecycleStarter.java:183)
at org.apache.maven.lifecycle.internal.LifecycleStarter.execute(LifecycleStarter.java:161)
at org.apache.maven.DefaultMaven.doExecute(DefaultMaven.java:320)
at org.apache.maven.DefaultMaven.execute(DefaultMaven.java:156)
at org.apache.maven.cli.MavenCli.execute(MavenCli.java:537)
at org.apache.maven.cli.MavenCli.doMain(MavenCli.java:196)
at org.apache.maven.cli.MavenCli.main(MavenCli.java:141)
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 org.codehaus.plexus.classworlds.launcher.Launcher.launchEnhanced(Launcher.java:290)
at org.codehaus.plexus.classworlds.launcher.Launcher.launch(Launcher.java:230)
at org.codehaus.plexus.classworlds.launcher.Launcher.mainWithExitCode(Launcher.java:409)
at org.codehaus.plexus.classworlds.launcher.Launcher.main(Launcher.java:352)
Is it possible to set things up with the jar so that the import will work?
The above approach works fine when there is no jar involved.
The simple answer is that the path to the imported file is wrong
...
import "dataTypeMaps.stg"
...
The import will cause the file to be looked for starting at the root of the jar.
The above import would amount to the file being placed at...
final String urlName = new StringBuilder()
.append("jar:file:").append(templateJar.getAbsolutePath()).append("!")
.append("dataTypeMaps.stg").toString();
Why the behavior is different than when the template group file is on the native file system I do not know.
In order to get this to work I changed the classpath to include the jar file.
As this was done in the context of a Maven plugin, the plugin needs to change the classpath dynamically. This was done with the following code...
public void setTemplateJarName(String templateJarName) throws GeneratorException {
this.templateJarName = templateJarName;
final Thread ct = Thread.currentThread();
final ClassLoader pcl = ct.getContextClassLoader();
URL[] nurl;
try {
nurl = new URL[]{ new URL("file://"+templateJarName) };
} catch (MalformedURLException ex) {
throw new GeneratorException("could not load template jar", ex);
}
final URLClassLoader ucl = new URLClassLoader(nurl, pcl);
ct.setContextClassLoader(ucl);
}
Double check your templates are really in your jar.
Use the following code :
If the templates are dispatched in a tree like this:
/-->resources
+--> c/ (many .st and .stg files)
+--> cpp/ (many .st and .stg files)
+--> java/ (many .st and .stg files)
+--> c.stg
+--> cpp.stg
+--> java.stg
The content of java.stg is:
group Java;
import "java"
doNothing() ::= <<>>
To load all the files in one call :
URL url = getClass().getResource( "/resources/" + templateName );
STGroup group = new STGroupFile( url, "utf-8", '<', '>' );
In my case templateName equals c.stg, cpp.stg or java.stg.
The relative path only works on the file system. If you want to import a template from the classpath, use the fully qualified name. This is the same, as when you would load the file from the classpath yourself, using Class::getResource(). Using the fully qualified name, also works for the filesystem.
So, assuming there are two template files:
src/main/resources/util/date.stg
src/main/resources/generator/class.stg
Then in class.stg you use the fully qualified name:
import "util/date.stg"