запуск класса Java из jar в coldfusion - NoClassDefFoundError

Я полностью застрял на этом. Я недостаточно понимаю холодный синтез и не могу найти ответ на этот вопрос, чтобы понять, что происходит не так.

Вот часть моего сценария coldfusion, которая является проблемой, используя общие имена для вещей здесь

<cfscript>
    function run() {

        var obj = createObject("java", "com.company.Run");

        var variable1= "string1";
        var variable2= "string2";
        var variable3= "string3";

        obj.init();

        var success = obj.runThis(variable1, variable2, variable3); <-- failing here
        return success;
    }
</cfscript>
<cfset success = run()>
<cfoutput>SUCCESS? #success#</cfoutput>

Код Java, к которому был получен доступ, находится в банке, которая скомпилирована и работает для простых методов внутри этого класса. например, я могу сделать это, используя код Java ниже скрипта coldfusion, и он работает без единой проблемы:

<cfscript>
    function run() {

        var obj = createObject("java", "com.company.Run");

        var variable= "string";

        obj.init();

        var success = obj.print(variable); <-- failing here
        return success;
    }
</cfscript>
<cfset success = run()>
<cfoutput>SUCCESS? #success#</cfoutput>


public static String print(String input) {
    return input;
}

То, что я пытаюсь запустить, — это мой первый сценарий холодного синтеза выше с такой идеей, внутри этого класса он запускает «runThis», который создает объект из другого класса, а затем запускает метод из этого объекта, который возвращает строку. Они оба находятся в одном банке, поэтому все они должны быть доступны и работать нормально, когда я запускаю только тесты junit для одного и того же кода. проблема здесь в том, чтобы втянуть его в холодный синтез и запустить его там:

public class Run {
public Run() {

    }
public String runThis(String variable1, String variable1, String variable3) throws Exception {

        try {
            MyObject object= new MyObject (variable1, variable2, variable3);
            return object.execute();
        } catch (Exception e) {
            return "error";
        }
    }
}

ошибка, которую я получаю:

"Error","http-bio-8500-exec-7","10/08/14","10:47:13",,"javax/ws/rs/WebApplicationException The specific sequence of files included or processed is: C:\ColdFusion11\cfusion\wwwroot\company\response.cfm, line: 77 "
java.lang.NoClassDefFoundError: javax/ws/rs/WebApplicationException
    at com.company.Run.runThis(Run.java:21)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
    at java.lang.reflect.Method.invoke(Unknown Source)
    at coldfusion.runtime.java.JavaProxy.invoke(JavaProxy.java:97)
    at coldfusion.runtime.CfJspPage._invoke(CfJspPage.java:2483)
    at cfresponse2ecfm1522673216$funcRUN.runFunction(C:\ColdFusion11\cfusion\wwwroot\company\response.cfm:77)
    at coldfusion.runtime.UDFMethod.invoke(UDFMethod.java:487)
    at coldfusion.runtime.UDFMethod$ArgumentCollectionFilter.invoke(UDFMethod.java:383)
    at coldfusion.filter.FunctionAccessFilter.invoke(FunctionAccessFilter.java:95)
    at coldfusion.runtime.UDFMethod.runFilterChain(UDFMethod.java:334)
    at coldfusion.runtime.UDFMethod.invoke(UDFMethod.java:231)
    at coldfusion.runtime.CfJspPage._invokeUDF(CfJspPage.java:2840)
    at cfresponse2ecfm1522673216.runPage(C:\ColdFusion11\cfusion\wwwroot\company\response.cfm:82)
    at coldfusion.runtime.CfJspPage.invoke(CfJspPage.java:246)
    at coldfusion.tagext.lang.IncludeTag.handlePageInvoke(IncludeTag.java:734)
    at coldfusion.tagext.lang.IncludeTag.doStartTag(IncludeTag.java:570)
    at coldfusion.filter.CfincludeFilter.invoke(CfincludeFilter.java:65)
    at coldfusion.filter.IpFilter.invoke(IpFilter.java:45)
    at coldfusion.filter.ApplicationFilter.invoke(ApplicationFilter.java:487)
    at coldfusion.filter.RequestMonitorFilter.invoke(RequestMonitorFilter.java:42)
    at coldfusion.filter.MonitoringFilter.invoke(MonitoringFilter.java:40)
    at coldfusion.filter.PathFilter.invoke(PathFilter.java:141)
    at coldfusion.filter.ExceptionFilter.invoke(ExceptionFilter.java:94)
    at coldfusion.filter.ClientScopePersistenceFilter.invoke(ClientScopePersistenceFilter.java:28)
    at coldfusion.filter.BrowserFilter.invoke(BrowserFilter.java:38)
    at coldfusion.filter.NoCacheFilter.invoke(NoCacheFilter.java:58)
    at coldfusion.filter.GlobalsFilter.invoke(GlobalsFilter.java:38)
    at coldfusion.filter.DatasourceFilter.invoke(DatasourceFilter.java:22)
    at coldfusion.filter.CachingFilter.invoke(CachingFilter.java:62)
    at coldfusion.CfmServlet.service(CfmServlet.java:219)
    at coldfusion.bootstrap.BootstrapServlet.service(BootstrapServlet.java:89)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:303)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
    at coldfusion.monitor.event.MonitoringServletFilter.doFilter(MonitoringServletFilter.java:42)
    at coldfusion.bootstrap.BootstrapFilter.doFilter(BootstrapFilter.java:46)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
    at coldfusion.inspect.weinre.MobileDeviceDomInspectionFilter.doFilter(MobileDeviceDomInspectionFilter.java:121)
    at coldfusion.bootstrap.BootstrapFilter.doFilter(BootstrapFilter.java:46)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:220)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:122)
    at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:501)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:170)
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:98)
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:116)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:422)
    at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1040)
    at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:607)
    at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:313)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
    at java.lang.Thread.run(Unknown Source)
Caused by: java.lang.ClassNotFoundException: javax.ws.rs.WebApplicationException
    at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1718)
    at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1569)
    ... 56 more

У меня такое ощущение, что я неправильно создаю экземпляр объекта MyObject или что именно здесь код дает сбой. Удаление этого, кажется, позволяет коду работать, но, очевидно, не даст мне того, к чему я стремлюсь.


person wondergoat77    schedule 08.10.2014    source источник
comment
Помимо com.company.*, какие еще пакеты содержит ваш пользовательский jar-файл? Исключение ссылается на javax.ws.rs.WebApplicationException, который, как я полагаю, уже включен в качестве одного из основных jar-файлов CF. Это включено в вашу нестандартную банку? Может быть конфликт.. Трудно сказать, поскольку я вижу в трассировке как NoClassDefFoundError, так и ClassNotFoundException:/   -  person Leigh    schedule 08.10.2014
comment
не включая это непосредственно в моем классе, но хорошая идея проверить   -  person wondergoat77    schedule 08.10.2014
comment
Любые другие внешние пакеты в банке, кроме com.company.* ? Также вы можете успешно создать экземпляр этого класса из CF и сбросить его? т.е. test = createObject("java", "javax.ws.rs.WebApplicationException"); writeDump(test);   -  person Leigh    schedule 08.10.2014
comment
Я был неправ, проверил, и я импортирую javax.ws.rs.WebApplicationException, удалил его, и у меня есть новая ошибка, указывающая на пользовательское исключение ошибки. посмотреть, смогу ли я обойти, используя это тоже.   -  person wondergoat77    schedule 08.10.2014
comment
поскольку я удаляю ненужный код, я нахожу, что он ищет новые банки, я считаю, что моя проблема в том, что я не включил банки, необходимые в моем пользовательском классе для запуска его кода. работаю над исправлением этого сейчас.   -  person wondergoat77    schedule 08.10.2014
comment
вот и все, у меня пропали баночки, теперь работает! спасибо за помощь, опубликуйте это как ответ, и я отмечу как ответ на этот вопрос.   -  person wondergoat77    schedule 08.10.2014
comment
Только что увидел твой комментарий. Готово. Я создавал пример для демонстрации, поэтому включил и его. Даже если вы уже решили проблему, это может быть полезно для следующего парня :)   -  person Leigh    schedule 09.10.2014


Ответы (2)


Я сильно подозреваю, что в вашей банке отсутствует одна или несколько зависимостей.

У меня нет доступа к CF11 на данный момент, но вы можете воспроизвести подобную трассировку, экспортировав проект в банку, НО опустив некоторые из необходимых классов. Например, я создал фиктивные версии ваших двух классов (см. ниже). Обратите внимание, что MyObject ссылается на третий класс — YetAnotherClass. Затем я экспортировал все в банку, но намеренно исключил YetAnotherClass.

Используя ваш тестовый код, я могу успешно вызвать print(). Однако когда код вызывает runThis(), возникает аналогичная ошибка. NoClassDefFoundError, вызванный ClassNotFoundException, потому что я забыл включить его в банку.

Примечание. Я тестирую с CF10.

Код CF

<cfscript>
    obj = createObject("java", "com.company.Run");
    result = obj.print("testing...");
    writeDump(result);

    obj.init();
    result = obj.runThis("john", "doe", "atlanta");
    writeDump(result);
</cfscript>

Трассировка стека ошибок:

java.lang.NoClassDefFoundError: com/othercompany/YetAnotherClass
    at com.company.MyObject.<init>(MyObject.java:10)
    at com.company.Run.runThis(Run.java:9)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
    ......
    at java.lang.Thread.run(Thread.java:662)
Caused by: java.lang.ClassNotFoundException: com.othercompany.YetAnotherClass
    at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1688)
    at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1533)

Выполнить

package com.company;

public class Run {

    public Run() {
    }

    public String runThis(String var1, String var2, String var3) throws Exception {
        MyObject object= new MyObject(var1, var2, var3);
        return object.execute();
    }

    public static String print(String input) {
        return input;
    }
}

Мой объект

package com.company;

import java.util.Date;
import com.othercompany.YetAnotherClass;

public class MyObject {

    private YetAnotherClass other;
    public MyObject(String first, String last, String city) {
        this.other = new YetAnotherClass();
    }

    public String execute() {
        return "Method execute invoked at "+ new Date();
    }
}

YetAnotherClass (другой пакет)

package com.othercompany;

public class YetAnotherClass {

    public YetAnotherClass() {
        // do nothing to keep it simple
    }

}
person Leigh    schedule 08.10.2014

Лучший способ реализовать такого рода интеграцию с Java — начать с создания экземпляра. Итак, сначала запустите свой код создания и выгрузите результат... что вы видите?

<cfset obj = createObject("java", "com.company.Run")/>
<cfdump var="#obj#"/>

Затем выгрузите функцию init() (которую я не вижу в вашем классе, но, возможно, она является частью суперкласса):

<cfset obj = obj.init()/> // assuming it returns an instance of Run
<cfdump var="#obj#"/>

Что вам показывает свалка? Вы обязательно должны увидеть runThis как метод класса.

Наконец, проработайте метод runThis. Имейте в виду, что переменные, которые вы передаете, должны быть строковыми типами Java - это, вероятно, ваша проблема. Если они не того типа, то аргументы вызывают другую сигнатуру метода. Вместо полезного сообщения типа «У меня есть runThis, но это неправильные аргументы или типы» Java просто выдает «метод не найден» (поскольку вы можете перегрузить метод, передав разные аргументы).

Если это проблема со строковым типом, попробуйте использовать JavaCast() в вызове метода, как показано ниже:

var variable1= Javacast("String","string1");

Установка типа таким образом обычно позволяет сортировать ваши данные через порог между Java и CF как правильный тип.

Этот пост на тему Java и CF несколько устаревший, но в нем есть несколько полезных подходов.

Надеюсь это поможет.

person Mark A Kruger    schedule 08.10.2014
comment
(Редактировать) Все это хорошие шаги по устранению неполадок, но я не знаю, является ли проблема отсутствием javacast. Предполагая, что это полная трассировка, исключения предполагают, что при создании экземпляра класса MyObject существует более фундаментальная проблема, такая как зависимость от отсутствующего класса или возможный конфликт версий, который проявляется при попытке создать экземпляр другого класса. Это полные догадки, поскольку я точно не знаю, как кодируются пользовательские классы или что они на самом деле делают... :) - person Leigh; 08.10.2014
comment
Спасибо. Я попытался преобразовать все свои значения в строку, используя javacast, и, похоже, это не решило проблему. - person wondergoat77; 08.10.2014
comment
Я посмотрю, что я могу опубликовать, это около 400 строк кода, и многие из них являются собственностью компании, в которой я работаю, поэтому не могу поделиться всем. - person wondergoat77; 08.10.2014
comment
Ли, я понимаю, о чем вы говорите... но зачем ему использовать obj.print()... который является частью суперкласса, а? и не использовать runThis(), который является частью подкласса? Если бы у него был такой классовый конфликт, разве он не проявился бы, как бы он ни звонил? может быть нет... - person Mark A Kruger; 08.10.2014
comment
@wondergoat77- Обычно (хотя и не всегда) ошибки NoClassDef или ClassNotFound указывают на конфликт версий или отсутствующую зависимость. Итак, ответ на предыдущий вопрос: есть ли у jar какие-либо внешние зависимости, которые помогут расшифровать, что означает NoClassDef/ClassNotFound в трассировке. Если нет, то соответствующей частью кода, вероятно, являются imports, любые static блоки или объявления и конструктор класса. - person Leigh; 08.10.2014
comment
Эй, попробуйте сделать это ВСЕ встроенным... пропустите init(), например createobject(java,com.company.Run).runThis(var1, var2, var3); ... или, возможно, С инициализацией, но все еще в строке, как в createObject(...).init().runThis() - person Mark A Kruger; 08.10.2014
comment
@MarkAKruger - Ну, obj.print - это статический метод Run. Похоже, ошибка возникает, когда он пытается создать экземпляр другого класса, т.е. MyObject. Если в этом классе есть ссылка на другой отсутствующий класс или блок static, который по какой-либо причине не может быть завершен, вы можете не увидеть ошибку, пока не попытаетесь создать экземпляр MyObject, т.е. вызвать runThis(). Опять же, я просто догадываюсь, основываясь на ограниченной доступной информации... ;) - person Leigh; 08.10.2014
comment
о... попался. Итак, runThis нужны другие объекты, а print просто возвращает примитивы? - person Mark A Kruger; 08.10.2014
comment
(Изменить) Именно, он создает экземпляры других классов. Похоже, именно тогда возникает проблема. Кроме того, Run.print() является статическим, поэтому вам даже не нужно создавать экземпляр класса Run, чтобы использовать его. - person Leigh; 08.10.2014
comment
Да, я сильно подозреваю, что вам не хватает зависимости. Я получаю точно такую ​​же трассировку (NoClassDefFoundError, вызванную ClassNotFoundException) с CF10, если я экспортирую проект в банку, но опускаю некоторые зависимости классов. - person Leigh; 09.10.2014
comment
Ли, я потеряла твой адрес электронной почты. У меня есть кое-что для вас, если вы свяжетесь со мной напрямую. - person Mark A Kruger; 10.10.2014
comment
@MarkAKruger - Извините, я не видел вашего комментария. Когда несколько человек оставляют комментарии, я думаю, С.О. отправляет уведомления только тогда, когда используется синтаксис @ + имя пользователя (за исключением автора, конечно). Моя электронная почта находится в моем профиле, кстати :) - person Leigh; 20.10.2014
comment
@leigh Я слепой? Я не вижу его там. - person Mark A Kruger; 20.10.2014
comment
Нет. Плохо, я только что заметил, что это поле помечено как закрытое. Я временно добавил его в свой профиль. Кстати, я отправил сообщение через ваш блог. Не уверен, что это прошло. - person Leigh; 20.10.2014