10.04.2009, 18:25 | #1 |
Участник
|
DAX40 #if.never в LedgerBondServer_RU
Привет.
В LedgerBondServer_RU в classdeclaration стоит макрос (закоментированный) #if.never. Я его откоментировал, посмотрел посопоставлял, закоментировал обратно, но ... система считает что он определен и продолжает выводить логи по сопоставлениям проводок. Сам класс я удалял, восстанавливал, чистил использование данных - не помогло. Есть идеи как избавится от #if.never ? |
|
10.04.2009, 18:40 | #2 |
Member
|
Сделайте компиляцию всего класса.
__________________
С уважением, glibs® |
|
10.04.2009, 18:47 | #3 |
Боец
|
Что-то припоминается, что вроде обновление перекрёстных ссылок помогает при подобных проблемах. Попробуйте запустить ТОЛЬКО для этого класса (по контекстному меню).
Возможно и ошибаюсь... |
|
10.04.2009, 18:54 | #4 |
Участник
|
|
|
10.04.2009, 18:56 | #5 |
Участник
|
|
|
10.04.2009, 19:06 | #6 |
Administrator
|
Причина может быть только одна в этом случае. Это что-то неоткомпилировалось.
Обновление перекрестных ссылок выполняет глобальную компиляцию и как следствие - перекомпилирует что неоткомпилировалось. Общее решение для таких случаев - перекомпилировать класс, в котором определен макрос и его наследников, т.е. сделать инкрементную компиляцию класса, в котором определен макрос.
__________________
Возможно сделать все. Вопрос времени |
|
10.04.2009, 19:28 | #7 |
MCTS
|
А если в ClassDeclaration ввести пробел, или другое изменение, которое не изменяет сам код, а потом сохранить и перекомпилировать класс?
|
|
12.04.2009, 19:23 | #8 |
Боец
|
Опишу проблему - возможно, корень и решение общее.
Проблема Некорректное обновление класса-наследника при смене его родителя. Воспроизведение 1. Создаём класс-наследник RunBase 2. Создаём в этом классе произвольный метод и вызываем в нём любой метод базового класса, напр: this.saveLast(); 3. Компилируем. 4. Отвязываем класс от RunBase, т.е. делаем его самостоятельным, не наследником (убираем extends RunBase). Компилируем. Симптомы Что видим - класс всё-равно остался наследником RunBase. (об этом свидетельствует отсутствие ошибок в нашем методе, где вызывается метод базового класса. При выполнении происходит вызов методов родителя). Как его не компилируй, как не модифицируй и снова компилируй, а от RunBase он не отвязывается. Инкрементная компиляция RunBase также не помогает. Решение a. Раньше лечил так: экспорт класса, удаление из системы, импорт b. Нашлось более изящное решение - обновление перекрестных ссылок именно для проблемного класса. Но не по контекстному меню, а из главного меню IDE. Итак: 1) Tools->DevelopmentTools->CrossReference->Periodic->Update 2) В фильтре появившегося диалога устанавливаем фильтр на поле Имя=ВашКласс 3) Выполняется мгновенно, после чего с классом всё в порядке. Что именно происходит внутри, и что конкретно исправляет этот недочёт компилятора - разбираться уж не стал. Может поможет. (ещё раз обращу внимание, что нужно обновить CrossReference из меню IDE, а не по контексту. По контексту (как я предложил в 1-ом посту) не помогает) |
|
|
За это сообщение автора поблагодарили: belugin (5), f18 (1), alex55 (1). |
12.04.2009, 21:53 | #9 |
Administrator
|
Цитата:
Сообщение от DSPIC
Опишу проблему - возможно, корень и решение общее.
Проблема Некорректное обновление класса-наследника при смене его родителя. Воспроизведение 1. Создаём класс-наследник RunBase 2. Создаём в этом классе произвольный метод и вызываем в нём любой метод базового класса, напр: this.saveLast(); 3. Компилируем. 4. Отвязываем класс от RunBase, т.е. делаем его самостоятельным, не наследником (убираем extends RunBase). Компилируем. Симптомы Что видим - класс всё-равно остался наследником RunBase. (об этом свидетельствует отсутствие ошибок в нашем методе, где вызывается метод базового класса. При выполнении происходит вызов методов родителя). Как его не компилируй, как не модифицируй и снова компилируй, а от RunBase он не отвязывается. Инкрементная компиляция RunBase также не помогает. Выполнил пп. 1-4. Получил следующие симптомы: 1. Класс НЕ остался наследником RunBase. Об этом свидетельствует: а) пустое поле Extends в свойствах класса (хотя я допускаю, что оно просто смотрит на ClassDeclaration) б) невозможность выбрать метод из списка. в) невозможность принудительно указать другой метод (например this.getLast()) 2. Существующая строчка this.saveLast() в моем новом методе не "пострадала" и честно проходит компиляцию. Закомментаривание ее и последующая компиляция погоды не делают. Т.е. при раскомментировании - она снова проходит компиляцию. Не пробовал глобальную компиляцию. Думаю, что должна помочь. Почему я скептически отношусь к идеям про "волшебные" перекрестные ссылки. Делов том, что аксапта при компиляции записывает откомпилированный код в отдельное поле таблички UtilElements. Т.е. каждый метод имеет свое "откомпилированное" значение. Эта табличка лежит в *.aod-шнике. Соответственно - зачем нужна инкрементная компиляция? Чтобы пробежаться по всем наследникам и заново "пересобрать" ИХ откомпилированный ранее код (во время компиляции - код родителя как бы "копируется" в код наследника, т.е. конечный класс собирается "по чертежам" всех своих родителей). Что получается здесь. Класс - то мы отвязали от RunBase (это подтверждается тем, что инкрементная компиляция RunBase до нашего класса не доходит, т.к. список классов для инкрементной компиляции генерируется на основе исходного кода, а не откомпилируемого). Однако, отвязка получилась некорректной - ранее скопированные (необходимые для компиляции наследника) копии родительских методов остались в откомпилированном коде. И удалить их можно увы - только путем удаления всего откомпилированного кода. При попытке удаления и создания метода - вызов saveLast() все равно "разрешается" в любом методе - что приводит к выводу - что этот метод в откомпилированном коде сохраняется при самом объекте (метод saveLast и только он был скопирован с родителя, но не был удален при отвязке родителя). Что происходит, когда класс удаляется и снова импортируется. Ведь наверняка Вы экспорт/импорт делали без сохранения ID. А коли так - то нисколько не удивительно, что ошибки появились - ведь объекты в UtilElements идентифицируются по ID-шникам, который у Вас изменился. А соответственно - старая информация от компиляции не подтянулась. Поэтому - то, что построение перекрестных ссылок приводит к нужному эффекту лишь подтверждает мысль о том, что глобальная компиляция также исправит сей эффект. Хотя - имеет смысл проверить.
__________________
Возможно сделать все. Вопрос времени Последний раз редактировалось sukhanchik; 12.04.2009 в 22:58. |
|
13.04.2009, 00:29 | #10 |
Боец
|
Цитата:
Попробовал.
Выполнил пп. 1-4. Получил следующие симптомы: 1. Класс НЕ остался наследником RunBase. Об этом свидетельствует: а) пустое поле Extends в свойствах класса (хотя я допускаю, что оно просто смотрит на ClassDeclaration) б) невозможность выбрать метод из списка. в) невозможность принудительно указать другой метод (например this.getLast()) Цитата:
При попытке удаления и создания метода - вызов saveLast() все равно "разрешается" в любом методе - что приводит к выводу - что этот метод в откомпилированном коде сохраняется при самом объекте (метод saveLast и только он был скопирован с родителя, но не был удален при отвязке родителя).
Цитата:
Делов том, что аксапта при компиляции записывает откомпилированный код в отдельное поле таблички UtilElements. Т.е. каждый метод имеет свое "откомпилированное" значение. Эта табличка лежит в *.aod-шнике.
Соответственно - зачем нужна инкрементная компиляция? Чтобы пробежаться по всем наследникам и заново "пересобрать" ИХ откомпилированный ранее код (во время компиляции - код родителя как бы "копируется" в код наследника, т.е. конечный класс собирается "по чертежам" всех своих родителей). Я таки залез в \Classes\xRefUpdate. Оказывается, не в перекрёстных ссылках дело, а в банальном X++: Dictionary::aodFlush(); sukhanchik, не знаю, как это решение ложится на описанный Вами механизм хранения откомпилированного кода. По большому счету, это всё не так уж важно: как оно там хранится, и как это всё можно объяснить - это более низкий уровень. Главное, что есть проблема (будем надеяться, что её пофиксят) и найдено простое решение. Глобальная компиляция - это пушкой по воробьям. |
|
13.04.2009, 11:25 | #11 |
Участник
|
решение предложенное DSPIC - помогло - спасибо!
Итак что было сделано - обновление перекрестных ссылок через Tools->DevelopmnetTools->ApplicationObjects->Refresh AOD (вводим имя класса) Затем ОБЯЗАТЕЛЬНО перекомпилировать класс (без компиляции таблетка не работает :-) ) Всем спасибо - удачи!!! |
|
16.04.2009, 12:19 | #12 |
Moderator
|
Часть темы выделена сюда:
Рассуждения на тему: X++ компилируемый или интерпретируемый язык?
__________________
Андрей. |
|
24.01.2013, 16:43 | #13 |
Участник
|
Похожая проблема.
При одновременной работе на 2х клиентах (на одном в дебаггере, второй для шпаргалки, и если на одном что-то сохраняю, на втором делаю восстановить) после очередного изменения ВНЕЗАПНО возникли ошибки в 2 классах (их сейчас не трогала, а вчера были сделаны изменения типа инфо(енум)), BookTransCalc_Purch_OnDelivery_RU и BookTransCalc_Purch_RU, первый является потомком второго. Родитель сообщает, что BookTransCalc_Purch_OnDelivery_RU не является классом, а первый ругается на переменные, объявленные в родителе. Все изменения, сделанные мною на моем слое, удалила. В потомке все равно высвечиваются изменения на моем слое, при сравнении показывает только разницу в "свойствах", на моем слое выполнять "called from", в оригинале выполнять на "server" (это наследовалось из родителя). Запустила обновление перекрестных ссылок, как было указано выше, но процесс продолжается уже полчаса... Т.е. все проблемы, по идее должны быть решены инкрементной компиляцией. НО: при ее выполнении возникает "Ошибка времени выполнения: DictClass Объект не инициализирован" Как исправить проблему? |
|
24.01.2013, 17:42 | #14 |
Участник
|
Проблему устранила перезагрузка АОСа.
|
|
Теги |
aod, compilation, cross-reference, flush, incorrect, refresh, update, интерпретатор, интерпретируемый, компилятор, компиляция, обновление, ошибка, перекрестные ссылки, наследование, macros |
|
|