问题遇到的现象和发生背景
使用FreeMaker构造自己的模板,在idea中能够正确运行;但是,打包发布后,报告java.lang.NoClassDefFoundError: freemarker/template/Configuration错误!!
程序采用Groovy 语言,idea 创建的Groovy工程。
问题相关代码,请勿粘贴截图
package cn.edu.cup.system
import com.google.common.base.CaseFormat
import freemarker.template.Configuration
import freemarker.template.Template
import freemarker.template.TemplateException
import javax.swing.JFileChooser
import javax.swing.JTabbedPane
import javax.swing.JTextField
import java.awt.BorderLayout
import java.awt.event.ActionEvent
import static freemarker.template.Configuration.VERSION_2_3_31;
/**
* Created by LiXiaoping on 2017/3/2.
*/
class GrailsAuxGuiFrame extends GenericGuiFrame {
//------------------------------------------------------------------------------------------------------------------
Configuration configuration;
def grailsAuxDcoument
def status
def currentProject
def sourceDomain
def sourceInstance
def sourceInput
def currentSetting
def targetDomain
def textInputs = [:]
def actionButtons = [:]
def templateTabs = [:]
def targetTabs = [:]
def mainTabs
//------------------------------------------------------------------------------------------------------------------
GrailsAuxGuiFrame(GrailsAuxDocument document) {
grailsAuxDcoument = document
}
//------------------------------------------------------------------------------------------------------------------
/**
* 打开一个文件选择对话框
*/
def openProjectPath = {
def o = new JFileChooser()
o.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY)
if (grailsAuxDcoument.projectPath) {
o.setCurrentDirectory(new File(grailsAuxDcoument.projectPath))
}
def ok = o.showOpenDialog(null)
if (ok == JFileChooser.APPROVE_OPTION) {
grailsAuxDcoument.projectPath = o.getSelectedFile().absolutePath
currentProject.text = grailsAuxDcoument.projectPath
}
}
def createTargetFile = {
// 第一步:创建一个Configuration对象,直接new一个对象。构造方法的参数就是freemarker对于的版本号。
configuration = new Configuration(VERSION_2_3_31);
File templateDir = new File(grailsAuxDcoument.templatePath)
if (templateDir.exists()) {
configuration.setDirectoryForTemplateLoading(templateDir)
println("找到模板了...")
grailsAuxDcoument.basicFiles.each { e ->
println("处理:" + e.value)
try {
// 第四步:加载一个模板,创建一个模板对象。
Template template = configuration.getTemplate(e.value);
// 目标文件名
def jname
if (e.key == "Entity.java") {
jname = grailsAuxDcoument.targetDir + "\\" +
grailsAuxDcoument.model.get("EntityName") + ".java"
} else {
jname = grailsAuxDcoument.targetDir + "\\" +
grailsAuxDcoument.model.get("EntityName") + e.key
}
// 第六步:创建一个Writer对象,一般创建一FileWriter对象,指定生成的文件名。
Writer out = new FileWriter(new File(jname));
// 第七步:调用模板对象的process方法输出文件。
template.process(grailsAuxDcoument.model, out);
// 第八步:关闭流。
out.close();
// 显示
File rf = new File(jname)
targetTabs.get(e.key).text = rf.text
} catch (IOException ex) {
throw new RuntimeException(ex);
} catch (TemplateException ex) {
throw new RuntimeException(ex);
}
}
mainTabs.selectedIndex = 1
}
}
def commonAction(ActionEvent evt) {
def actionName = evt.actionCommand
println("通用事件处理:${actionName} -- ${evt}")
println("source: ${evt.source}")
println("source Key: ${evt.source.name}")
status.text = actionName
def key = evt.source.name
def value
if (evt.source instanceof JTextField) {
value = ((JTextField) evt.source).text
grailsAuxDcoument.model.put(key, value)
if (key == "EntityName") {
def tn = CaseFormat.LOWER_CAMEL.to(CaseFormat.LOWER_UNDERSCORE, value)
grailsAuxDcoument.model.put("tableName", tn)
textInputs.get("tableName").text = tn
}
}
switch (actionName) {
case "打开工程目录":
openProjectPath()
break
case "生成目标文档":
createTargetFile()
break
}
showStatus()
}
def showStatus() {
//显示结果
def s = ""
grailsAuxDcoument.model.each { eit ->
s += grailsAuxDcoument.modelName.get(eit.key) +
':' +
grailsAuxDcoument.model.get(eit.key) + " "
}
currentSetting.setText(s)
// 按钮状态
def ok = true;
grailsAuxDcoument.model.each { e ->
ok = ok && !((String) e.value).isEmpty()
}
actionButtons.get("生成目标文档").setEnabled(ok);
}
//------------------------------------------------------------------------------------------------------------------
//工具栏
def theToolBar = {
swing.panel(layout: new BorderLayout(), constraints: BorderLayout.NORTH) {
toolBar(constraints: BorderLayout.NORTH) {
label(text: "操作流程:")
grailsAuxDcoument.guideStrings.each { e ->
actionButtons.put(e, button(text: e, actionPerformed: { evt -> commonAction(evt) }))
label(text: "->")
}
separator()
label(text: "当前操作:")
status = label(text: "")
separator()
label(text: "当前工程:")
currentProject = label(text: grailsAuxDcoument.projectPath)
separator()
}
// 输入各种参数
toolBar(constraints: BorderLayout.SOUTH) {
grailsAuxDcoument.modelName.each { eit ->
label(text: eit.value)
textInputs.put(eit.key,
textField(id: eit.key, text: grailsAuxDcoument.model.get(eit.key), actionPerformed: { evt -> commonAction(evt) }))
separator()
}
currentSetting = label(text: "")
}
}
}
//------------------------------------------------------------------------------------------------------------------
//界面
def mainTabPanel = {
mainTabs = swing.tabbedPane(id: "tabs", tabLayoutPolicy: JTabbedPane.SCROLL_TAB_LAYOUT) {
//模板
tabbedPane(name: "模板", tabLayoutPolicy: JTabbedPane.SCROLL_TAB_LAYOUT) {
grailsAuxDcoument.templates.each { e ->
scrollPane(name: e.key) {
templateTabs.put(e.key, textArea(name: e.key, id: "temp_" + e.key, text: e.value))
}
}
}
//目标
tabbedPane(name: "目标", tabLayoutPolicy: JTabbedPane.SCROLL_TAB_LAYOUT) {
grailsAuxDcoument.templates.each { e ->
scrollPane(name: e.key) {
targetTabs.put(e.key, textArea(name: e.key, id: "target_" + e.key))
}
}
}
}
showStatus()
}
//------------------------------------------------------------------------------------------------------------------
}
运行结果及报错内容
模板齐全,可以开工...
Exception in thread "main" java.lang.NoClassDefFoundError: freemarker/template/Configuration
at java.base/java.lang.Class.getDeclaredMethods0(Native Method)
at java.base/java.lang.Class.privateGetDeclaredMethods(Class.java:3166)
at java.base/java.lang.Class.privateGetPublicMethods(Class.java:3191)
at java.base/java.lang.Class.getMethods(Class.java:1904)
at java.desktop/com.sun.beans.introspect.MethodInfo.get(MethodInfo.java:70)
at java.desktop/com.sun.beans.introspect.ClassInfo.getMethods(ClassInfo.java:71)
at java.desktop/java.beans.Introspector.getTargetMethodInfo(Introspector.java:1045)
at java.desktop/java.beans.Introspector.getBeanInfo(Introspector.java:461)
at java.desktop/java.beans.Introspector.getBeanInfo(Introspector.java:204)
at groovy.lang.MetaClassImpl.lambda$addProperties$24(MetaClassImpl.java:3513)
at java.base/java.security.AccessController.doPrivileged(Native Method)
at groovy.lang.MetaClassImpl.doPrivileged(MetaClassImpl.java:3545)
at groovy.lang.MetaClassImpl.addProperties(MetaClassImpl.java:3513)
at groovy.lang.MetaClassImpl.reinitialize(MetaClassImpl.java:3495)
at groovy.lang.MetaClassImpl.initialize(MetaClassImpl.java:3488)
at org.codehaus.groovy.reflection.ClassInfo.getMetaClassUnderLock(ClassInfo.java:272)
at org.codehaus.groovy.reflection.ClassInfo.getMetaClass(ClassInfo.java:314)
at org.codehaus.groovy.runtime.metaclass.MetaClassRegistryImpl.getMetaClass(MetaClassRegistryImpl.java:269)
at org.codehaus.groovy.vmplugin.v8.Selector$InitSelector.getMetaClass(Selector.java:403)
at org.codehaus.groovy.vmplugin.v8.Selector$MethodSelector.setCallSiteTarget(Selector.java:1010)
at org.codehaus.groovy.vmplugin.v8.IndyInterface.fallback(IndyInterface.java:351)
at org.codehaus.groovy.vmplugin.v8.IndyInterface.access$000(IndyInterface.java:49)
at org.codehaus.groovy.vmplugin.v8.IndyInterface$FallbackSupplier.get(IndyInterface.java:281)
at org.codehaus.groovy.vmplugin.v8.IndyInterface.lambda$fromCache$1(IndyInterface.java:301)
at java.base/java.util.HashMap.computeIfAbsent(HashMap.java:1134)
at org.codehaus.groovy.vmplugin.v8.CacheableCallSite.getAndPut(CacheableCallSite.java:61)
at org.codehaus.groovy.vmplugin.v8.IndyInterface.lambda$fromCache$2(IndyInterface.java:298)
at org.codehaus.groovy.vmplugin.v8.IndyInterface.doWithCallSite(IndyInterface.java:367)
at org.codehaus.groovy.vmplugin.v8.IndyInterface.fromCache(IndyInterface.java:295)
at cn.edu.cup.system.SpringBootAuxToolA.main(SpringBootAuxToolA.groovy:14)
Caused by: java.lang.ClassNotFoundException: freemarker.template.Configuration
at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:581)
at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:178)
at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:521)
... 30 more