Вопрос [Java] Вопрос касательно планирования архитектуры библиотеки, уязвимых мест и неопределенного поведения при явном кривом использовании функционала

Начинающий
Начинающий
Статус
Оффлайн
Регистрация
5 Июн 2025
Сообщения
500
Реакции
24
Драсте, я уже довольно долго работаю над большим фреймворком пересекающимся с нативными библиотеками, и всё чаще и чаще возникает вопрос касательно неопределенного поведения библиотеки при использовании её "абы как". Что-бы было чуть понятнее - приведу пример:
К примеру у нас есть библиотека для работы которой нужно создавать контекст, но есть какой-то объект который требует для своей работы контекст, но из-за специфики этого объекта и его поведения полностью предостеречь от кривого поведения при исчезновении контекста не получится.

Как пример, представим что это пул объектов(NativeObject) которые создаются в самом контексте, можно при создании пула проверить есть ли контекст, при получении объекта(obtain) и отсутствии свободных оных(NativeObject) в пуле(при создании пулом нового объекта через контекст) можно сделать проверку на существование контекста, но при этом если контекст в моменте теряется, пул сам по себе не пропадает, NativeObject закрепленные за пулом так-же не пропадают (максимум - можно освободить нативные ресурсы NativeObject которыми владеет пул, но это сильно осложнит реализацию самого NativeObject).

При освобождении без проверки контекста можно сильно наебаться и крашнуть JVM нативным вызовом, что не есть хорошо, с проверкой - метод бесполезен. Т.е. при пропаже контекста фактически весь пул становится мусорным объектом который не может функционировать, это тоже не хорошо, но поскольку вкинуть пул в пакет к контексту(в имплементацию а не как доп. функционал из коробки) нельзя(потому-что имплементация фактически закрытая за исключением 1-2 методов) - я в целом хрен знает что с этим можно придумать.

Казалось бы не делает ничего free() и obtain() - ну пусть и не делают, но мне это тоже как-то не внушает доверие что такое можно считать за нормальное поведение кода, поэтому собсна вопрос и запостил, что-бы понять где еще рамки нормы можно натянуть на глобус, а где - тотальный треш

Пример кода:
Проблема:
Expand Collapse Copy
class NativeObjectPool {
    List<NativeObject> obtainedObjects;
    List<NativeObject> freeObjects;

    ExamplePool(int size) {
        checkContext();
        obtainedObjects = new List<>(size);
        freeObjects = new List<>(size);
    }

    NativeObject obtain() {
        // Если есть свободный объект
        if (freeObjects.size() > 0) {
            NativeObject obj = freeObjects.remove(0);
            obtainedObjects.add(obj);
            return obj;
        }
        
        // Если свободных объектов нет и нужно его создать
        if (!checkSize()) {
            return null; // превышен лимит размера
        }
        
        checkContext(); // Проверяем существование контекста
        NativeObject obj = Context.instance().createNativeObject();
        obtainedObjects.add(obj);
        return obj;
    }
    
    void free(@NotNull NativeObject obj) {
        // Проблема тут, проверить контекст мы можем, но что делать если нам вернули такой объект без контекста?
        // Если вызвать метод NativeObject#reset() мы можем получить JVM-краш из-за отсутствия нативного контекста
        // Просто игнорировать?...
        
        if (contextExists() && obtainedSources.contains(obj)) {
            obtainedSources.remove(obj);
            obj.reset();
            freeSources.add(obj);
        }
    }

    boolean checkSize() { ... }
}

far release.jpg
 
Назад
Сверху Снизу