Netty ExceptionInInitializerError - PullRequest
       14

Netty ExceptionInInitializerError

0 голосов
/ 25 мая 2018

Я в проекте IOT и пытаюсь разобраться с кривой обучения и странным углом подхода.Я программист .Net, и кажется, что библиотека перехода на Netty основана на Java.Наш клиент уже исследует это, чтобы разместить его на своих устройствах, и настаивает на использовании HTTP вместо MQTT, потому что они не хотят, чтобы конфигурация брандмауэра была нормальным фактором.

Итак, первое, что я должен позволить вамЯ знаю, что вначале я пытался использовать DotNetty в качестве клиента и посредника, но я не мог придумать головы или хвоста библиотеки, потому что в ней нет документации, и я не мог связать объекты, которые я видел в обозревателе объектов, с тем, что явидел в нетти документы.Затем мне пришло в голову, что, возможно, я мог бы сделать что-то похожее на то, что я вижу в Xamarin, где у меня есть четкий доступ к библиотекам Java из кода C #.Это привело меня к LKVM, который позволил мне конвертировать файл jar Netty в файл DLL.

Итак, пока я использую Visual Studio и C #, теперь я могу следовать учебным пособиям и документам Netty, которые позволили немного продвинуться вперед.

Я написал небольшое консольное приложениеэто должно действовать как устройство IOT с клиентом Netty.Я использовал созданную DLL для написания клиента.Я получил ошибку при попытке подключения и предположил, что, поскольку у меня нет брокера, он просто не нашел конечную точку.Поэтому сегодня я написал код сервера.Как только я закончил, я попытался снова подключить устройство и получил ту же ошибку.

Затем я запустил Fiddler, чтобы я мог проверить движение и увидел, что его не было.Таким образом, ошибка возникает до того, как будет предпринята любая попытка подключения.

Итак, прежде чем идти дальше, вот код клиента:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using JSON = Newtonsoft.Json.JsonConvert;
using io.netty.util;
using io.netty.bootstrap;
using io.netty.buffer;
using io.netty.channel;
using io.netty.channel.nio;
using io.netty.channel.socket;
using io.netty.channel.socket.nio;
using io.netty.handler.codec.http;
using io.netty.handler.codec.http.websocketx;
using io.netty.handler.codec.http.websocketx.extensions.compression;
using io.netty.handler.ssl;
using io.netty.handler.ssl.util;
using java.io;
using java.net;
using io.netty.util.concurrent;

namespace Device
{
    public class WebSocketClient
    {
        public string URL { get; set; }
        public URI Uri = null;
        public Uri netUri = null;
        public string Host;
        public int Port;
        public Channel Channel;
        public Bootstrap BootStrap = new Bootstrap();
        public WebSocketClientHandler Handler;
        public EventLoopGroup Group = new NioEventLoopGroup();
        public SslContext SslCtx = null;

        public WebSocketClient(string URL)
        {
            this.URL = URL;
            netUri = new Uri(this.URL);
            Uri = new URI(URL);
            Host = netUri.Host;
            Port = netUri.Port;//Unlike the Netty example, .Net knows the ws/wss ports.
            bool SSL = Port == 443;


            if (SSL)
            {
                SslCtx = SslContextBuilder.forClient().trustManager(InsecureTrustManagerFactory.INSTANCE).build();
            }

            Handler = new WebSocketClientHandler(WebSocketClientHandshakerFactory.newHandshaker(Uri, WebSocketVersion.V13, null, true, new DefaultHttpHeaders()));
            //BootStrap.group(Group).channel(new NioSocketChannel().GetType().handler(new ChannelInitializer(Handler, Host, Port, SslCtx))).connect(Host, Port).sync().channel();

        }

        public void Connect()
        {
            //Channel = BootStrap.connect(Host, Port).sync().channel();            
            //Channel = BootStrap.connect().sync().channel();
            //((Bootstrap)BootStrap.group(Group).channel(new NioSocketChannel().GetType()).handler(new ChannelInitializer(Handler, Host, Port, SslCtx))).connect(Host, Port).sync().channel();

            BootStrap = BootStrap.group(Group) as Bootstrap;
            BootStrap = BootStrap.channel(new NioSocketChannel().GetType()) as Bootstrap;
            BootStrap = BootStrap.handler(new ChannelInitializer(Handler, Host, Port, SslCtx)) as Bootstrap;            
            //BootStrap.remoteAddress(Host, Port);
            //BootStrap.localAddress(Host, Port);
            ChannelFuture cf = BootStrap.connect(Host, Port);
            cf = cf.sync();
            Channel = cf.channel();

            Handler.HandshakeFuture().sync();
        }

        public void Close()
        {
            Group.shutdownGracefully();
        }

        public void Ping()
        {
            WebSocketFrame frame = new PingWebSocketFrame(Unpooled.wrappedBuffer(new byte[] { 8, 1, 8, 1 }));
            Channel.writeAndFlush(frame);
        }

        public void Send(string content)
        {
            Channel.writeAndFlush(content);
            Channel.newPromise().addListener(new Listener());
        }

    }

    public class Listener : GenericFutureListener
    {
        public void operationComplete(Future f)
        {
            System.Console.WriteLine(JSON.SerializeObject(f.get()));
        }
    }
}

В конструкторе есть закомментированная строка, котораяимитирует то, что было в их примере клиента.Поскольку он был прикован цепью, трудно было сказать, откуда возникла ошибка.Итак, я перенес это в свою функцию соединения и отключил ее

В функции подключения в следующей строке я вижу первый признак неисправности:

ChannelFuture cf = BootStrap.connect(Host, Port);

Если я смотрю на объект в моих «часах», я вижу, чтоЭто похоже на ошибку уже присутствует.Выглядит это так:

{DefaultChannelPromise@67755d(failure: java.lang.ExceptionInInitializerError)}

Однако в этой строке она не выдает ошибку, а в следующей строке:

cf = cf.sync();

И трассировка стека выглядит следующим образом:

at io.netty.util.internal.PlatformDependent0.throwException(Exception )
   at io.netty.util.internal.PlatformDependent.throwException(Exception t)
   at io.netty.util.concurrent.DefaultPromise.rethrowIfFailed()
   at io.netty.util.concurrent.DefaultPromise.sync()
   at io.netty.channel.DefaultChannelPromise.sync()
   at io.netty.channel.DefaultChannelPromise.<bridge>sync()
   at io.netty.channel.DefaultChannelPromise.io.netty.channel.ChannelFuture/()Lio.netty.channel.ChannelFuture;sync()
   at Device.WebSocketClient.Connect() in c:\Users\ME\Documents\Visual Studio 2017\Projects\MQTT Sandbox\Device\WebSocketClient.cs:line 70
   at Device.Program.SocketTest() in c:\Users\ME\Documents\Visual Studio 2017\Projects\MQTT Sandbox\Device\Program.cs:line 106
   at Device.Program.Main(String[] args) in c:\Users\ME\Documents\Visual Studio 2017\Projects\MQTT Sandbox\Device\Program.cs:line 72

Единственное другое преимущество, которое у меня есть, заключается в том, что, если я исследую это исключение, в исключении есть под исключение (в отличие от внутреннего исключения), которое говорит: «Неизвестный размер указателя».Эта трассировка стека выглядит следующим образом:

enter image description here

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

Заранее благодарен за любую помощь!

Обновление Мне удалось извлечь лучшую трассировку стека из ChannelFuture cf = BootStrap.connect (Хост, порт);

May 29, 2018 8:25:37 AM io.netty.channel.DefaultChannelId defaultProcessId
WARNING: Failed to find the current process ID from ''; using a random value: -251539282
May 29, 2018 8:25:43 AM io.netty.channel.AbstractChannel$AbstractUnsafe register
WARNING: Force-closing a channel whose registration task was not accepted by an event loop: [id: 0x6312b48a]
java.lang.ExceptionInInitializerError
        at io.netty.util.internal.shaded.org.jctools.queues.LinkedArrayQueueUtil.modifiedCalcElementOffset(LinkedArrayQueueUtil.java:24)
        at io.netty.util.internal.shaded.org.jctools.queues.BaseMpscLinkedArrayQueue.offer(BaseMpscLinkedArrayQueue.java:308)
        at io.netty.util.concurrent.SingleThreadEventExecutor.offerTask(SingleThreadEventExecutor.java:330)
        at io.netty.util.concurrent.SingleThreadEventExecutor.addTask(SingleThreadEventExecutor.java:321)
        at io.netty.util.concurrent.SingleThreadEventExecutor.execute(SingleThreadEventExecutor.java:765)
        at io.netty.channel.AbstractChannel$AbstractUnsafe.register(AbstractChannel.java:479)
        at io.netty.channel.SingleThreadEventLoop.register(SingleThreadEventLoop.java:81)
        at io.netty.channel.SingleThreadEventLoop.register(SingleThreadEventLoop.java:74)
        at io.netty.channel.MultithreadEventLoopGroup.register(MultithreadEventLoopGroup.java:86)
        at io.netty.bootstrap.AbstractBootstrap.initAndRegister(AbstractBootstrap.java:333)
        at io.netty.bootstrap.Bootstrap.doResolveAndConnect(Bootstrap.java:163)
        at io.netty.bootstrap.Bootstrap.connect(Bootstrap.java:145)
        at io.netty.bootstrap.Bootstrap.connect(Bootstrap.java:126)
        at cli.Device.WebSocketClient.Connect(WebSocketClient.cs:70)
        at cli.Device.Program.SocketTest(Program.cs:106)
        at cli.Device.Program.Main(Program.cs:72)
Caused by: java.lang.IllegalStateException: Unknown pointer size
 at io.netty.util.internal.shaded.org.jctools.util.UnsafeRefArrayAccess.<clinit>(UnsafeRefArrayAccess.java:51)
        ... 11 more

May 29, 2018 8:25:43 AM io.netty.util.concurrent.DefaultPromise safeExecute
SEVERE: Failed to submit a listener notification task. Event loop shut down?
java.lang.NoClassDefFoundError: Could not initialize class io.netty.util.internal.shaded.org.jctools.util.UnsafeRefArrayAccess
        at io.netty.util.internal.shaded.org.jctools.queues.LinkedArrayQueueUtil.modifiedCalcElementOffset(LinkedArrayQueueUtil.java:24)
        at io.netty.util.internal.shaded.org.jctools.queues.BaseMpscLinkedArrayQueue.offer(BaseMpscLinkedArrayQueue.java:308)
        at io.netty.util.concurrent.SingleThreadEventExecutor.offerTask(SingleThreadEventExecutor.java:330)
        at io.netty.util.concurrent.SingleThreadEventExecutor.addTask(SingleThreadEventExecutor.java:321)
        at io.netty.util.concurrent.SingleThreadEventExecutor.execute(SingleThreadEventExecutor.java:765)
        at io.netty.util.concurrent.DefaultPromise.safeExecute(DefaultPromise.java:764)
        at io.netty.util.concurrent.DefaultPromise.notifyListeners(DefaultPromise.java:438)
        at io.netty.util.concurrent.DefaultPromise.trySuccess(DefaultPromise.java:104)
        at io.netty.channel.DefaultChannelPromise.trySuccess(DefaultChannelPromise.java:84)
        at io.netty.channel.AbstractChannel$CloseFuture.setClosed(AbstractChannel.java:1148)
        at io.netty.channel.AbstractChannel$AbstractUnsafe.register(AbstractChannel.java:491)
        at io.netty.channel.SingleThreadEventLoop.register(SingleThreadEventLoop.java:81)
        at io.netty.channel.SingleThreadEventLoop.register(SingleThreadEventLoop.java:74)
        at io.netty.channel.MultithreadEventLoopGroup.register(MultithreadEventLoopGroup.java:86)
        at io.netty.bootstrap.AbstractBootstrap.initAndRegister(AbstractBootstrap.java:333)
        at io.netty.bootstrap.Bootstrap.doResolveAndConnect(Bootstrap.java:163)
        at io.netty.bootstrap.Bootstrap.connect(Bootstrap.java:145)
        at io.netty.bootstrap.Bootstrap.connect(Bootstrap.java:126)
        at cli.Device.WebSocketClient.Connect(WebSocketClient.cs:70)
        at cli.Device.Program.SocketTest(Program.cs:106)
        at cli.Device.Program.Main(Program.cs:72)

1 Ответ

0 голосов
/ 08 марта 2019

Я нашел решение и внедрил исправление в своей ветке IKVM.https://github.com/Draspax/ikvm8

В основном в классе io.netty.util.internal.shaded.org.jctools.util.UnsafeRefArrayAccess существует вызов UnsafeAccess.UNSAFE.arrayIndexScale (Object []. Class);который должен возвращать либо 4, либо 8, и небезопасная реализация IKVM не учитывает класс Object []., поэтому он возвращает значение по умолчанию 1. Я добавил массив объектов в качестве опции для arrayIndexScale, чтобы вернуть 4.

Надеюсь, они будут включены в https://github.com/wwrd/ikvm8, как только эти парни поддержат IKVM.

...