Проблема миграции на Java 11 из устаревшего кода - PullRequest
0 голосов
/ 22 января 2019

Мы переносим наш старый код, фактически довольно старый, на Java 11. У меня возникают проблемы при компиляции одного из классов.Пример кода:

package XXXX;

import java.lang.ref.*;
import sun.security.action.*;
import java.security.*;
import java.io.*;

class Converters
{
    private static Object lock;
    private static String converterPackageName;
    private static String defaultEncoding;
    public static final int BYTE_TO_CHAR = 0;
    public static final int CHAR_TO_BYTE = 1;
    private static final String[] converterPrefix;
    private static SoftReference[] classCache;
    static /* synthetic */ Class class$sun$io$Converters;

    private static String getConverterPackageName() {
        final String converterPackageName = Converters.converterPackageName;
        if (converterPackageName != null) {
            return converterPackageName;
        }
        String converterPackageName2 = AccessController.doPrivileged((PrivilegedAction<String>)new GetPropertyAction("file.encoding.pkg"));
        if (converterPackageName2 != null) {
            Converters.converterPackageName = converterPackageName2;
        }
        else {
            converterPackageName2 = "sun.io";
        }
        return converterPackageName2;
    }

    private static Class getConverterClass(final int n, final String s) throws UnsupportedEncodingException {
        String aliasName = null;
        if (!s.equals("ISO8859_1")) {
            if (s.equals("8859_1")) {
                aliasName = "ISO8859_1";
            }
            else if (s.equals("ISO8859-1")) {
                aliasName = "ISO8859_1";
            }
            else if (s.equals("646")) {
                aliasName = "ASCII";
            }
            else {
                aliasName = CharacterEncoding.aliasName(s);
            }
        }
        if (aliasName == null) {
            aliasName = s;
        }
        try {
            return Class.forName(getConverterPackageName() + "." + Converters.converterPrefix[n] + aliasName);
        }
        catch (ClassNotFoundException ex) {
            throw new UnsupportedEncodingException(aliasName);
        }
    }

    private static Object newConverter(final String s, final Class clazz) throws UnsupportedEncodingException {
        try {
            return clazz.newInstance();
        }
        catch (InstantiationException ex) {
            throw new UnsupportedEncodingException(s);
        }
        catch (IllegalAccessException ex2) {
            throw new UnsupportedEncodingException(s);
        }
    }

    static Object newConverter(final int n, final String s) throws UnsupportedEncodingException {
        final Class converterClass;
        synchronized (Converters.lock) {
            converterClass = getConverterClass(n, s);
        }
        return newConverter(s, converterClass);
    }

    private static Class getDefaultConverterClass(final int n) {
        boolean b = false;
        final SoftReference softReference = Converters.classCache[n];
        if (softReference != null) {
            final Class clazz = softReference.get();
            if (clazz != null) {
                return clazz;
            }
            Converters.classCache[n] = null;
        }
        String defaultEncoding = Converters.defaultEncoding;
        if (Converters.defaultEncoding != null) {
            b = true;
        }
        else {
            defaultEncoding = AccessController.doPrivileged((PrivilegedAction<String>)new GetPropertyAction("file.encoding"));
            if (defaultEncoding != null) {
                Converters.defaultEncoding = defaultEncoding;
                b = true;
            }
            else {
                defaultEncoding = "ISO8859_1";
            }
        }
        Class clazz2;
        try {
            clazz2 = getConverterClass(n, defaultEncoding);
            if (b) {
                Converters.classCache[n] = new SoftReference(clazz2);
            }
        }
        catch (UnsupportedEncodingException ex) {
            try {
                clazz2 = getConverterClass(n, "ISO8859_1");
            }
            catch (UnsupportedEncodingException ex2) {
                throw new InternalError("Cannot find default " + Converters.converterPrefix[n] + " converter class");
            }
        }
        return clazz2;
    }

    static Object newDefaultConverter(final int n) {
        final Class defaultConverterClass;
        synchronized (Converters.lock) {
            defaultConverterClass = getDefaultConverterClass(n);
        }
        try {
            return newConverter("", defaultConverterClass);
        }
        catch (UnsupportedEncodingException ex) {
            throw new InternalError("Cannot instantiate default converter class " + defaultConverterClass.getName());
        }
    }

    static /* synthetic */ Class class$(final String s) {
        try {
            return Class.forName(s);
        }
        catch (ClassNotFoundException ex) {
            throw new NoClassDefFoundError(ex.getMessage());
        }
    }

    static {
        Converters.lock = ((Converters.class$sun$io$Converters == null) ? (Converters.class$sun$io$Converters = class$("sun.io.Converters")) : Converters.class$sun$io$Converters);
        Converters.converterPackageName = null;
        Converters.defaultEncoding = null;
        converterPrefix = new String[] { "ByteToChar", "CharToByte" };
        Converters.classCache = new SoftReference[2];
    }
}

При компиляции с использованием javac Converter.java появляется следующее сообщение об ошибке:

import sun.security.action.*;
                   ^
  (package sun.security.action is declared in module java.base, which does not export it to the unnamed module)
Converters.java:47: error: cannot find symbol
                aliasName = CharacterEncoding.aliasName(s);
                            ^
  symbol:   variable CharacterEncoding
  location: class Converters
Converters.java:85: error: incompatible types: Object cannot be converted to Class
            final Class clazz = softReference.get();
                                                 ^
Note: Converters.java uses or overrides a deprecated API.
Note: Recompile with -Xlint:deprecation for details.
Note: Converters.java uses unchecked or unsafe operations.
Note: Recompile with -Xlint:unchecked for details.
3 errors

Я пытался экспортировать это с помощью --add--export java.base/sun.security=All-UNNAMED, это все ещевыдает ошибку.

Любая помощь?Также хотелось бы знать, есть ли другой способ удалить этот старый унаследованный код новым.

Ответы [ 2 ]

0 голосов
/ 25 января 2019

Начиная с Java 9, большинство внутренних API JDK недоступны во время компиляции (и в будущем они также будут недоступны во время выполнения). sun.security.action является внутренним пакетом, поэтому его следует избегать. В вашем случае вы можете просто удалить new GetPropertyAction("file.encoding.pkg") и заменить его на лямбду:

AccessController.doPrivileged((PrivilegedAction<Object>) () -> System.getProperty("prop"));
0 голосов
/ 22 января 2019

Как уже указывалось, это внутренние классы, которые не должны использоваться напрямую. Если рефакторинг выходит за рамки, вы должны использовать --add-export, и это должно работать!

Ваш --add-export аргумент неверен. Вам необходимо использовать правильный пакет для экспорта (sun.security.action в вашем случае) и имя вашего модуля (ВСЕ-НЕЗНАКОМЛЕНО, если вы не используете модули, все в заглавными буквами !).

Так что это должно быть --add-exports java.base/sun.security.action=ALL-UNNAMED

Из документации javac:

- add-exports module / package = other-module (, other-module) * Указывает пакет, который будет считаться экспортированным из его определяющего модуля в дополнительные модули или все безымянные модули, когда значение другой модуль ВСЕ-НЕИЗВЕСТЕН.

...