03.04.2012, 16:37 | #1 |
Модератор
|
Олицетворенный на сервере (RunAs) сеанс попытался вызвать метод, который доступен только на клиенте.
Класс выполняется на пакетном сервере (32-разрядном) Dynamics Ax 2009 Sp1 RU7
в одном методе, ошибка валится на строке : X++: boolean ado_findFieldGuid(FilePath _filePath, Filename _filename) { //Classes CCAdoConnection adoConnection; CCAdoCommand adoCommand; CCAdoRecordSet adoRecordSet; CCAdoFields adoFields; //Variables int i; FilePath connectionString = 'Driver={Microsoft dBASE Driver (*.dbf)};DriverID=277;Dbq='; boolean ret = false; ; connectionString = connectionString + _filePath + ';' ; new InteropPermission(InteropKind::ComInterop).assert(); adoConnection = new CCAdoConnection(); //<-- Ошибка: Олицетворенный на сервере (RunAs) сеанс попытался вызвать метод, который доступен только на клиенте. adoConnection.open(connectionString); adoCommand = new CCADOCommand(); adoCommand.activeConnection(adoConnection); .... Ранее выполнялось все нормально, код не менялся. Теперь на adoConnection = new CCAdoConnection(); ошибка. Кто подскажет куда дальше копать с проблемой?
__________________
This posting is provided "AS IS" with no warranties, and confers no rights. |
|
03.04.2012, 16:54 | #2 |
Axapta
|
Поставить у CCADOConnection (а заодно и прочих CCADO*) RunOn=Called from, если там стоит Client. Плюс см.http://blogs.msdn.com/b/aeremenk/arc...1/9566049.aspx
|
|
03.04.2012, 17:07 | #3 |
Модератор
|
Цитата:
Сообщение от oip
Поставить у CCADOConnection (а заодно и прочих CCADO*) RunOn=Called from, если там стоит Client. Плюс см.http://blogs.msdn.com/b/aeremenk/arc...1/9566049.aspx
__________________
This posting is provided "AS IS" with no warranties, and confers no rights. |
|
03.04.2012, 17:08 | #4 |
Участник
|
Цитата:
нашёл ответ на свой вопрос когда прочёл предыдущий пост, написанный одной минутой ранее
__________________
Дмитрий Последний раз редактировалось Damn; 03.04.2012 в 17:11. Причина: прочёл предыдущий пост |
|
03.04.2012, 19:34 | #5 |
Боец
|
Потому что классы CCADO* используются только в одной, какой-то русской функциональности работающей на клиенте, в AX2009 по крайней мере.
Последний раз редактировалось DSPIC; 03.04.2012 в 19:37. |
|
14.11.2013, 11:38 | #6 |
Участник
|
Если позволите, подниму тему.
С описанным в начале темы сообщением, когда на сервере вызывается класс с RunOn=Client и в результате получаем ошибку, вроде все понятно. Но недавно столкнулся с интересным моментом: имеется некий класс с RunOn=Server; в одном из его методов вызывается метод Global::fileNameNext(), при этом класс Global имеет RunOn=Called from, а метод Global::fileNameNext() объявлен следующим образом - static client server Filename fileNameNext(Filename _filename); однако в методе Global::fileNameNext() используется метод WinAPI::fileExists(), который в свою очередь является клиентским (RunOn=Client у класса WinAPI и модификатор client у метода fileExists()). Для начала вопрос: как вы думаете, как будет работать такая связка при обработке файлов на сервере (пути - сетевые). Я бы наверное сразу сказал, результатом будет ошибка "Олицетворенный на сервере (RunAs) сеанс попытался вызвать метод, который доступен только на клиенте...", но как показала практика - все работало нормально. Класс работал в пакете, проверялось наличие файлов, получались новые имена, файлы создавались/перемещались с новыми именами... Но, тут самое интересное! Все работало до поры, до времени. В один прекрасный момент таки появилась вышеописанная ошибка! Причем только на одном файле из нескольких сотен. Причем именно на этом файле она повторялась. Причем на всех других файлах она не проявлялась. Со временем выявился еще один такой уникальный файлик. С тех пор их только два. Честно, говоря полез проверять места выполнения всей цепочки только после того как получил ошибку. До этого просто не обратил внимание на наличие в fileNameNext() метода WinAPI::fileExists(). И даже после этого не стал сразу исправлять, а некоторое время последил за работой класса - ошибка больше не проявлялась на новых файлах и стабильно повторялась на двух файлах, на которых появлялась и ранее. Может кто-нибудь объяснить такое поведение Аксапты? P.S.: Метод Global::fileNameNext() ни кем не правился - живет на sys-слое. WinAPI::fileExists() - также. Kernel version: 5.0.1500.4570, Application version: 5.0.1500.3761 |
|
14.11.2013, 11:55 | #7 |
Участник
|
Проверьте какие права есть у пользователя, под которым запущен клиент Ax, на работу с этими двумя волшебными файлами.
Последний раз редактировалось handy-comp; 14.11.2013 в 12:00. |
|
14.11.2013, 12:23 | #8 |
Участник
|
Цитата:
Все файлики представляют собой XML-ки, выгружаемые из внешней системы. Вроде как все они создаются одинаково, с одинаковыми правами одним и тем же сервисом (пользователем). Конечно не исключаю ,что в процессе тестирования кто-нибудь мог положить эти файлы в папку обмена с другого места или подправить руками. Но достоверно узнать это сейчас не представляется возможным))) Кстати, поиском по форуму не нашел ни одного упоминания fileNameNext(). Неужели, этим методом действительно никто никогда не пользовался (ну кроме формы экспорта из АОТ)? P.S.: Забыл сказать, что я сам в мистику не верю, но ситуация имеет место быть... Очевидно, что я либо чего-то недопонимаю в механизме определения места выполнения кода, либо чего-то не учитываю. Поэтому и написал об этом на форуме, чтоб разобраться... Последний раз редактировалось androzavr; 14.11.2013 в 12:30. |
|
14.11.2013, 13:12 | #9 |
Участник
|
Чудес не бывает Запустите трассировку перед выполнением пакетного задания, использующего fileNameNext(), и потом посмотрите в TraceParcer'е, где именно какой метод выполнялся.
PS. Я так понимаю, речь о приложении AX 2009? Потому что в 2012 соотв. метод уже "различает", на клиенте он выполняется или на сервере. |
|
|
За это сообщение автора поблагодарили: androzavr (1). |
14.11.2013, 17:21 | #10 |
Участник
|
Ура! Вера в несуществование чудес получила очередное подтверждение...
Не дошел я до трассировки. Пока выбирал файлы для тестирования, наконец заметил отличие в тех, что вызывали ошибку и тех, что не вызывали ошибку - ошибочные файлы уже существовали в папке назначения, а нормальные все были новые. Соответственно сразу возникла мысль, что может все-таки fileNameNext() не всегда вызывается. Полез шерстить код и таки нашел чуть раньше вызов WinApiServer::fileExists(). Косяк - детский! Стыдно даже в нем признаваться, но дабы ни у кого не возникло вдруг веры в чудеса решил стерпеть и признаться... Все дело в невероятнейшем стечении обстоятельств! Тестировал создание дубликатов файлов на разработческом приложении без пакетника, а на тестовом сервере не попадалось одинаковых имен файлов. Удивительное совпадение. Итак, извиняюсь за преждевременно поднятую панику и, если позволите, пока свежо, пару вопросов не совсем по теме (не знаю как здесь обозначить "оффтоп"): 1) gl00mie, можете пояснить о какой трассировке и главное "TraceParcer'е" Вы говорили? Это термины из Ax2012? Или речь все-таки о Профайлере кода в Ax2009? Ведь я правильно понял, что это точно не трассировка SQL и не трассировка, которая включается галочками на вкладке "Разработка" в параметрах пользователя? 2) Если не сложно можете выслать мне код метода fileNameNext() с Ax2012, который различает на каком уровне он выполняется. Просто интересно посмотреть как Они это сделали, потому что у самого было несколько разных идей, но остановился пока на самом простом варианте (добавил в свой класс похожий метод)). Думаю не нарушит сильно авторских прав и лицензионных соглашений... Ответить можно в личку. Тему засорять больше не посмею... |
|
14.11.2013, 18:55 | #11 |
Участник
|
Возник еще один вопрос, касательно ошибки "Олицетворенный на сервере (RunAs) сеанс попытался вызвать метод, который доступен только на клиенте". Пока игрался с классами, вызывающими ошибку, заметил, что она не перехватывается try-catch'ем. Вместо сообщения "Произошла такая-то ошибка..." выполнение прерывается в месте вызова клиентского класса и вываливает инфолог.
Можно-ли с этим что-то поделать? Я понимаю, конечно, что такого просто-напросто нельзя допускать. И отправлять в рабочую среду код, пусть и обрабатывающий такого рода ошибки нельзя, просто хочется понять почему она не перехватывается. Такое поведение сделано специально, чтоб горе-программисты не пытались писать кривой код? Или ошибку обработать все-таки можно? |
|
15.11.2013, 00:46 | #12 |
Участник
|
Обработка такой ошибки кодом приложения не реализована, насколько я понимаю, потому что тут из-за отсутствия клиентской части среды времени выполнения как бы отсутствует кусок приложения (тот, что должен выполняться на клиенте), и при этом выполняющийся на сервере кусок приложения от него зависит, раз вызывает соотв. клиентский код. Это примерно то же, что отсутствие нужного ActiveX'а или .NET-сборки, обнаруживающееся во время выполнения: если такой компонент грузится неявно через статические привязки в приложении, то среда времени выполнения не знает, как можно продолжить выполнение приложения без него, и прерывает выполнение приложения в текущей сессии по всему стеку вызовов, без оглядки на обработчики исключений.
|
|
|
За это сообщение автора поблагодарили: S.Kuskov (1). |
15.11.2013, 12:29 | #13 |
Участник
|
Цитата:
Ну а в 2009 есть 2 класса WinAPI и WinAPIServer. У которых соответственно RunOn: Client, Server. И различия между ними в том что, в-первом случае вызовы функций идут через WinApi, а во-втором уже через .Net. Связано это скорее всего с переходом серверов на WinServ2008. Из чего следует, что бы использовать Global::fileNameNext(), надо вводить условие проверки, где запускается функция и какую WinApi использовать. ПС WinAPIServer потом тоже пришлось приглаживать, так как начались валиться ошибки такого плана "//Сбой запроса на разрешение типа "FileIOPermission"." ПС2 Кстати с ADO* такая же беда, по-этому в новых функция, и по возможности в старых, перешёл на использование .Net. Последний раз редактировалось d_alexe; 15.11.2013 в 12:36. |
|
15.11.2013, 14:01 | #14 |
Участник
|
Цитата:
Код: -caslevel=disable |
|
|
За это сообщение автора поблагодарили: d_alexe (1). |
11.12.2013, 16:41 | #15 |
Сенбернар
|
Подниму-ка тему...
Ситуация : - из пакета, выполняющегося на сервере - из класса "внутри" этого пакета, у которого (класса) аттрибут RunOn = Server - вызывается InventMovement::setAutoReserving(salesLine); - client static boolean setAutoReserving(Common buffer) , что приводит к ошибке "Олицетворенный на сервере (RunAs) сеанс попытался вызвать метод, который доступен только на клиенте." === И что теперь? Поправить InventMovement::setAutoReserving() ? Зачем вообще там client static ? Наведите на мысль, pls..
__________________
Best Regards, Roman |
|
|
За это сообщение автора поблагодарили: gl00mie (1). |
11.12.2013, 17:02 | #16 |
Участник
|
А версия приложения какая? В 2012 написано вот что:
Цитата:
This method is called from the SalesTableForm class when you enter a new sales line. If the quantity that is entered must be reserved, the method checks for the available inventory. If inventory is not found, the method returns the InventOnHandCheckReserve dialog box to the user. From here, the user can change the quantity on the order line or ignore the dialog box and continue.
|
|
11.12.2013, 17:04 | #17 |
Сенбернар
|
Упс, виноват..
DAX2009 Kernel 5.0.1500.4570 Appl 5.0.1500.2116 EE
__________________
Best Regards, Roman |
|
11.12.2013, 17:19 | #18 |
Участник
|
В 2009-й все то же самое, только без пояснительных комментариев.
А зачем, собственно, дергать этот код в пакете? Если нужно, чтобы количества в создаваемых строках автоматом зарезервировались, достаточно перед созданием строки прописать в ней SalesLine.Reservation = ItemReservation::Automatic. Последний раз редактировалось gl00mie; 11.12.2013 в 17:23. |
|
|
За это сообщение автора поблагодарили: RVS (2). |
11.12.2013, 17:25 | #19 |
Сенбернар
|
Цитата:
Просто - метод, который вызывает setAutoReserving() - писался задолго до меня.. и специально - для запуска в пакете, только вот "пакет" был - на клиенте, в стиле 3.0.. и товар там - хороший, сколько его не резервируй, не отгружай - он есть всегда, и его много )) Спасибо, решение найдено.
__________________
Best Regards, Roman Последний раз редактировалось RVS; 11.12.2013 в 17:30. |
|
27.09.2016, 15:54 | #20 |
Участник
|
Если можно , подниму проблему:
имеется функционал, который импортирует записи из внешнего сервиса (документы, эксель файлы и т.д.), который запускается как в обычном режиме, так и в пакетном режиме. После доработок, которые были сделаны с целью сохранять документы на сервере непосредственно после импорта их с внешнего сервиса ( ранее это делалось по нажатию кнопки на форме). И теперь если выставить запуск пакетника с такими параметрами: Я получаю ошибку, описанную выше. Всем классам поставил свойство Called from , как и menu item-у , который непосредственно запускает периодическую операцию. Согласно стека ошибок он валится на создании DictClass объекта. Хотя сам DictClass стоит Called from и это ещё более странно. Стек ошибки ниже: Если выставить единоразовый запуск - ошибка остается, что в принципе логично Что можно сделать в данной ситуации, кроме как не загружать в docuref документы в пакетном режиме? Заранее благодарю за ответы. Ax2009 kernel 5.0.1500.6491 app version 5.0.1500.6491 Последний раз редактировалось user_ax; 27.09.2016 в 15:56. Причина: too big mockup |
|
|
Опции темы | Поиск в этой теме |
Опции просмотра | |
|