国产中标麒麟Linux部署dotnet core 环境并运行项目 (二) 部署运行控制台项目
背景
在上一篇文章安装dotnet core,已经安装好dotnet core了。之前只是安装成功了dotnet, 输入dotnet --info,可以确认安装成功了,但是在运行代码时,还是报错了,本章记录在部署好dotnet core后,到能运行控制台程序当中的错误。
首先将项目用vs发布一下,然后把文件放到中标麒麟的系统上,在文件夹打开终端,执行 dotnet **.dll,结果如下:
[root@gumis02 PublishOutput]# dotnet Beyondbit.ConsoleFrameworkNetStandard.IntegrationTests.dll
Failed to load \ufffd=l, error: libunwind.so.8: cannot open shared object file: No such file or directory
Failed to bind to CoreCLR at '/home/dotnet/shared/Microsoft.NETCore.App/2.0.7/libcoreclr.so'
[root@gumis02 PublishOutput]#
错误 error : libunwind.so.8: cannot open shared object file: No such file or directory
修复此问题的解决方案是安装 libunwind
手动源码安装 libunwind
libunwind的源代码现在已经托管到github上了,libunwind github 地址
我安装的是最新版1.2.1, 输入下面命令安装:
wget https://github.com/libunwind/libunwind/releases/download/v1.2.1/libunwind-1.2.1.tar.gz
tar -xf libunwind-1.2.1.tar.gz
cd libunwind-1.2.1
CFLAGS=-fPIC ./configure #添加编译参数
make CFLAGS=-fPIC
make CFLAGS=-fPIC install
安装成功后,再执行dotnet **.dll,会发现依然报错ibunwind.so.8: cannot open shared object file: No such file or directory
在输入以下命令修复:
[root@gumis02 dotnet]# find / -name libunwind.so.8
/home/.Trash-0/files/libunwind-1.2.1/src/.libs/libunwind.so.8
/home/NetCoreSdk/libunwind-1.2.1/src/.libs/libunwind.so.8
/usr/local/lib/libunwind.so.8
[root@gumis02 dotnet]# ln -s /usr/local/lib/libunwind.so.8 /lib64/
[root@gumis02 dotnet]# ln -s /usr/local/lib/libunwind.so.8 /lib
[root@gumis02 dotnet]# find / -name libunwind-x86_64.so.8
/home/.Trash-0/files/libunwind-1.2.1/src/.libs/libunwind-x86_64.so.8
/home/NetCoreSdk/libunwind-1.2.1/src/.libs/libunwind-x86_64.so.8
/usr/local/lib/libunwind-x86_64.so.8
[root@gumis02 dotnet]# ln -s /usr/local/lib/libunwind-x86_64.so.8 /lib64/
[root@gumis02 dotnet]# ln -s /usr/local/lib/libunwind-x86_64.so.8 /lib
输入后,再执行dotnet **.dll,发现上面的问题已经消失。但是出现新的错误提示:
FailFast: Couldn't find a valid ICU package installed on the system. Set the configuration flag System.Globalization.Invariant to true if you want to run with no globalization support.
at System.Environment.FailFast(System.String)
at System.Globalization.GlobalizationMode.GetGlobalizationInvariantMode()
at System.Globalization.GlobalizationMode..cctor()
at System.Globalization.CultureData.CreateCultureWithInvariantData()
at System.Globalization.CultureData.get_Invariant()
at System.Globalization.CultureData.GetCultureData(System.String, Boolean)
at System.Globalization.CultureInfo.InitializeFromName(System.String, Boolean)
at System.Globalization.CultureInfo.Init()
at System.Globalization.CultureInfo..cctor()
at System.StringComparer..cctor()
at System.AppDomainSetup.SetCompatibilitySwitches(System.Collections.Generic.IEnumerable`1<System.String>)
at System.AppDomain.PrepareDataForSetup(System.String, System.AppDomainSetup, System.Security.Policy.Evidence, System.Security.Policy.Evidence, IntPtr, System.String, System.String[], System.String[])
\u5df2\u653e\u5f03 (core dumped)
[root@gumis02 PublishOutput]#
下一步,准备修复这个错误.
错误 Couldn't find a valid ICU package installed on the system. Set the configuration flag System.Globalization.Invariant to true if you want to run with no globalization support.
查找资料显示,这是NET Core 全球化的模式,可见微软的文章 NET Core Globalization Invariant Mode
摘取一段原文说明背景
Globalization rules and the data that represents those rules frequently change, often due to country-specific policy changes (for example, changes in currency symbol, sorting behavior or time zones). Developers expect globalization behavior to always be current and for their applications to adapt to new data over time. In order to keep up with those changes, .NET Core (and the .NET Framework, too) depends on the underlying OS to keep up with these changes.
Relying on the underlying OS for globalization data has the following benefits:
- .NET apps have the same globalization behavior on a given OS as native apps (assuming they also rely on the OS).
- .NET apps do not have to carry this data.
- The .NET team doesn't have to maintain this data themselves (it's very expensive to do this!).
Globalization support has the following potential challenges for applications:
- Different behavior across OSes (and potentially OS versions).
- Installing/carrying the ICU package on Linux (~28 MB).
Note: On Linux, .NET Core relies on globalization data from ICU. For example, .NET Core Linux Docker images install this component. Globalization data is available on Windows and macOS as part of their base installs.
上文提到依赖 ICU Package,可点击链接去查看。
有两种解决方案:
- 在runtimeconfig.json中添加以下配置即可,不想纠结原理的就使用这种方式即可:
"configProperties": {
"System.Globalization.Invariant": true
}
完整的在runtimeconfig.json 如下:
{
"runtimeOptions": {
"tfm": "netcoreapp2.0",
"framework": {
"name": "Microsoft.NETCore.App",
"version": "2.0.0"
},
"configProperties": {
"System.Globalization.Invariant": true
}
}
}
注意
这种方式,证明了是可以解决问题的,但是他开启了Globalization.Invariant Mode 模式,在简单的应用下,程序可以正常运行,但是在遇到复杂的应用很有可能会遇到一个异常,System.ArgumentNullException: SafeHandle cannot be null,见我正式项目的运行结果,这个异常在github上有很多人提到,如:
- System.ArgumentNullException: "SafeHandle cannot be null" on every http request
- Packed .net core 2.0 application using log4net not working under Ubuntu
- Tracking: System.ArgumentNullException "SafeHandle cannot be null" in http hello
我的测试项目就是用了log4net导致的,目前net corefx团队收到了反馈已经在着手解决了。要想终极解决此问题,需要用以下第二种方式来解决,安装 ICU Package模块。
- 安装ICU Package
ICU Package
我们使用源码的方式安装icu. 我选择的是59.1版本,输入以下命令:
wget http://download.icu-project.org/files/icu4c/59.1/icu4c-59_1-src.tgz
tar -xzvf icu4c-59_1-src.tgz
cd icu/source
./configure --prefix=/usr/local/icu
make
make install
参看是否安装成功:
[root@gumis02 ~]# icu-config --version
59.1
[root@gumis02 ~]# icuinfo
icuinfo: error while loading shared libraries: libicutu.so.59: cannot open shared object file: No such file or directory
看到安装成功了,但是查看具体信息会提示缺少 libicutu.so.59,其他缺少的dll,同样处理。
输入以下命令查找,并映射so文件:
[root@gumis02 ~]# find / -name libicutu.so.59
/home/NetCoreSdk/icu/source/lib/libicutu.so.59
/home/NetCoreSdk/icu2/source/lib/libicutu.so.59
/usr/lib/libicutu.so.59
/usr/local/icu/lib/libicutu.so.59
[root@gumis02 ~]# ln -s /usr/local/icu/lib/libicutu.so.59 /lib64/
[root@gumis02 ~]# ln -s /usr/local/icu/lib/libicui18n.so.59 /lib64/
[root@gumis02 ~]# ln -s /usr/local/icu/lib/libicuuc.so.59 /lib64/
[root@gumis02 ~]# ln -s /usr/local/icu/lib/libicudata.so.59 /lib64/
[root@gumis02 ~]# ln -s /usr/local/icu/lib/libicudata.so.59 /lib64/
[root@gumis02 ~]# icuinfo
<icuSystemParams type="icu4c">
<param name="copyright"> Copyright (C) 2016 and later: Unicode, Inc. and others. License & terms of use: http://www.unicode.org/copyright.html </param>
<param name="product">icu4c</param>
<param name="product.full">International Components for Unicode for C/C++</param>
<param name="version">59.1</param>
<param name="version.unicode">9.0</param>
<param name="platform.number">4000</param>
<param name="platform.type">Linux</param>
<param name="locale.default">zh_CN</param>
<param name="locale.default.bcp47">zh-CN</param>
<param name="converter.default">UTF-8</param>
<param name="icudata.name">icudt59l</param>
<param name="icudata.path"></param>
<param name="cldr.version">31.0.1</param>
<param name="tz.version">2017b</param>
<param name="tz.default">PRC</param>
<param name="cpu.bits">64</param>
<param name="cpu.big_endian">0</param>
<param name="os.wchar_width">4</param>
<param name="os.charset_family">0</param>
<param name="os.host">x86_64-unknown-linux-gnu</param>
<param name="build.build">x86_64-unknown-linux-gnu</param>
<param name="build.cc">gcc</param>
<param name="build.cxx">g++</param>
<param name="uconfig.internal_digitlist">1</param>
<param name="uconfig.have_parseallinput">1</param>
<param name="uconfig.format_fastpaths_49">1</param>
</icuSystemParams>
ICU Initialization returned: U_ZERO_ERROR
Plugins are disabled.
参考:
install ICU-61.1
安装完成后,再测试正式的项目,执行成功了,数据插入到数据库了。
运行测试
HelloWorld 项目
采用配置了 runtimeconfig.json中添加以下配置
"configProperties": {
"System.Globalization.Invariant": true
}
HelloWorld程序运行测试:
Microsoft .NET Core Shared Framework Host
Version : 2.0.7
Build : 2d61d0b043915bc948ebf98836fefe9ba942be11
[root@gumis02 ConsoleTest2]# dotnet ConsoleApp2.dll
FailFast: Couldn't find a valid ICU package installed on the system. Set the configuration flag System.Globalization.Invariant to true if you want to run with no globalization support.
at System.Environment.FailFast(System.String)
at System.Globalization.GlobalizationMode.GetGlobalizationInvariantMode()
at System.Globalization.GlobalizationMode..cctor()
at System.Globalization.CultureData.CreateCultureWithInvariantData()
at System.Globalization.CultureData.get_Invariant()
at System.Globalization.CultureData.GetCultureData(System.String, Boolean)
at System.Globalization.CultureInfo.InitializeFromName(System.String, Boolean)
at System.Globalization.CultureInfo.Init()
at System.Globalization.CultureInfo..cctor()
at System.StringComparer..cctor()
at System.AppDomainSetup.SetCompatibilitySwitches(System.Collections.Generic.IEnumerable`1<System.String>)
at System.AppDomain.PrepareDataForSetup(System.String, System.AppDomainSetup, System.Security.Policy.Evidence, System.Security.Policy.Evidence, IntPtr, System.String, System.String[], System.String[])
\u5df2\u653e\u5f03 (core dumped)
[root@gumis02 ConsoleTest2]# dotnet ConsoleApp2.dll
Hello World!
[root@gumis02 ConsoleTest2]#
正式控制台项目
在runtimeconfig.json中添加以下配置即可,不想纠结原理的就使用这种方式即可:
"configProperties": {
"System.Globalization.Invariant": true
}
上面的这种方式,我使用helloworld程序是能正常运行的,但是在正式的项目中,用到了log4net,运行的话,会报其他的错误:
[root@gumis02 PublishOutput]# dotnet Beyondbit.ConsoleFrameworkNetStandard.IntegrationTests.dll
Unhandled Exception: System.Reflection.TargetInvocationException: Exception has been thrown by the target of an invocation. ---> System.ArgumentNullException: SafeHandle cannot be null.
Parameter name: pHandle
at System.ThrowHelper.ThrowArgumentNullException(ExceptionArgument argument, ExceptionResource resource)
at System.StubHelpers.StubHelpers.SafeHandleAddRef(SafeHandle pHandle, Boolean& success)
at Interop.GlobalizationInterop.GetSortKey(SafeSortHandle sortHandle, String str, Int32 strLength, Byte* sortKey, Int32 sortKeyLength, CompareOptions options)
at System.Globalization.CompareInfo.GetHashCodeOfStringCore(String source, CompareOptions options, Boolean forceRandomizedHashing, Int64 additionalEntropy)
at System.Collections.Hashtable.GetHash(Object key)
at System.Collections.Hashtable.InitHash(Object key, Int32 hashsize, UInt32& seed, UInt32& incr)
at System.Collections.Hashtable.Insert(Object key, Object nvalue, Boolean add)
at System.Collections.Hashtable.set_Item(Object key, Object value)
at log4net.Core.LevelMap.Add(Level level)
at log4net.Repository.LoggerRepositorySkeleton.AddBuiltinLevels()
at log4net.Repository.LoggerRepositorySkeleton..ctor(PropertiesDictionary properties)
at log4net.Repository.Hierarchy.Hierarchy..ctor(PropertiesDictionary properties, ILoggerFactory loggerFactory)
--- End of inner exception stack trace ---
at System.RuntimeTypeHandle.CreateInstance(RuntimeType type, Boolean publicOnly, Boolean& canBeCached, RuntimeMethodHandleInternal& ctor)
at System.RuntimeType.CreateInstanceSlow(Boolean publicOnly, Boolean skipCheckThis, Boolean fillCache, StackCrawlMark& stackMark)
at System.Activator.CreateInstance(Type type, Boolean nonPublic)
at System.Activator.CreateInstance(Type type)
at log4net.Core.DefaultRepositorySelector.CreateRepository(String repositoryName, Type repositoryType)
at log4net.Core.DefaultRepositorySelector.CreateRepository(Assembly repositoryAssembly, Type repositoryType, String repositoryName, Boolean readAssemblyAttributes)
at log4net.Core.LoggerManager.GetLogger(Assembly repositoryAssembly, String name)
at log4net.LogManager.GetLogger(Type type)
at Beyondbit.Framework.Core.Proxy.Proxy.SetSessionToContext(ISession session) in E:\\u5de5\u4f5c\u533a\03 \u4e92\u8054\u7f51\00 Beyondbit Infrastructure\\u5f00\u53d1\u6846\u67b6\3.0\Beyondbit.Framework\Core\Proxy\Proxy.cs:line 117
at Beyondbit.Framework.Core.Proxy.Proxy.CreateClassProxy[T]() in E:\\u5de5\u4f5c\u533a\03 \u4e92\u8054\u7f51\00 Beyondbit Infrastructure\\u5f00\u53d1\u6846\u67b6\3.0\Beyondbit.Framework\Core\Proxy\Proxy.cs:line 82
at Beyondbit.Framework.Core.Proxy.Proxy.CreateObject[T]() in E:\\u5de5\u4f5c\u533a\03 \u4e92\u8054\u7f51\00 Beyondbit Infrastructure\\u5f00\u53d1\u6846\u67b6\3.0\Beyondbit.Framework\Core\Proxy\Proxy.cs:line 55
at Beyondbit.ConsoleFrameworkNetStandard.IntegrationTests.Program.Insert() in E:\\u5de5\u4f5c\u533a\03 \u4e92\u8054\u7f51\00 Beyondbit Infrastructure\\u5f00\u53d1\u6846\u67b6\3.0\Test\Integration\ConsoleFrameworkNetStandard\Program.cs:line 22
at Beyondbit.ConsoleFrameworkNetStandard.IntegrationTests.Program.Main(String[] args) in E:\\u5de5\u4f5c\u533a\03 \u4e92\u8054\u7f51\00 Beyondbit Infrastructure\\u5f00\u53d1\u6846\u67b6\3.0\Test\Integration\ConsoleFrameworkNetStandard\Program.cs:line 14
\u5df2\u653e\u5f03 (core dumped)
[root@gumis02 PublishOutput]#
可以看到错误的调用堆栈,是由log4net运行出来的,这个很有可能是里面需要增加全局资源文件,因为看到了System.Globalization命名空间,不过呢,已经能看到了正常的net 错误堆栈,可以证明dotnet 已经在中标麒麟的操作系统上能运行了。
这个异常产生的原因我在上面已经说明了,要解决这个问题,不能开启Globalization.Invariant,必须讲他设置成false,同时安装ICU Packet解决
在runtimeconfig.json中添加以下配置即可,不想纠结原理的就使用这种方式即可:
"configProperties": {
"System.Globalization.Invariant": false
}
执行结果:
[root@gumis02 PublishOutput]# dotnet Beyondbit.ConsoleFrameworkNetStandard.IntegrationTests.dll
用户插入成功
[root@gumis02 PublishOutput]#
dotnet core 2.0 在真实项目上,还有很多的未知,还等待我去解决和探索。 Keep going.
总结:
经过一个星期的摸爬滚打终于在中标麒麟Linux系统上成功的运行了dotnet core 正式的项目,而不是helloworld程序。心力交瘁中也收获了很多东西,在这一个星期中,我一个linux盲,也掌握了很多linux命令,如:mkdir,ln, find,ll,ldd 等等。当然用了一个星期的时间,主要还是自己两方面的问题:
- 对linux不熟悉,基本是linux盲
- 对net core 底层的编译知识还不熟悉,在摸索当中
后续还要加强两方面的学习,学无止境
后续
成功的是控制台程序,下一步开始把做好的dotnet core web api + 前端 vuejs项目部署到麒麟系统上,我预计到又是一段打怪路程,通关后,我会继续将通关记录分享出来。
最后晒下截图:
国产中标麒麟Linux部署dotnet core 环境并运行项目 (二) 部署运行控制台项目的更多相关文章
- Linux - 安装 dotnet core 环境
Linux - 安装 dotnet core 环境 系统环境:CentOS7 官方安装指导 https://www.microsoft.com/net/learn/get-started/linux ...
- 国产中标麒麟Linux部署dotnet core 环境并运行项目 (一) 安装dotnet core
背景 根据我之前写的文章 将 Net 项目升级 Core项目经验:(一)迁移Net项目为Net Core\Standard项目,我们将公司内部最核心的ORM框架迁移到net core 上面,并在win ...
- 国产中标麒麟Linux部署dotnet core 环境并运行项目 (三) 部署运行WEB API项目
部署dotnet Core Web API 上一步的文章,是我们公司最核心的一个ORM组件,在中标麒麟系统完成了一个插入数据的任务,这一步是将正式的从dot net framework 迁移到 dot ...
- 部署Dotnet Core应用到Kubernetes(二)
前一篇文章,概念性地介绍了K8s的一些基础组件,如Pod.部署和服务.这篇文章,我打算写写如何使用YAML清单定义和配置这些资源. 实际上,在K8s集群中创建对象有几种方式 - 命令,或声明.两种 ...
- 边缘化搭建 DotNet Core 2.1 自动化构建和部署环境(下)
写在前面 本篇文章是上一篇边缘化搭建 DotNet Core 2.1 自动化发布和部署(上)的后续操作,本文主要讲解如何开启Docker Remote API,开启Remote API后的权限安全问题 ...
- Linux安装.Net core 环境并运行项目
原文:Linux安装.Net core 环境并运行项目 一 安装环境 1. 从微软官网下载 Linux版本的.NetCoreSdk 2.0 安装包 打开终端: 第一步: sudo yum insta ...
- Docker 部署Dotnet Core MVC项目
原文:Docker 部署Dotnet Core MVC项目 1.dotnet core创建项目 dotnet new mvc -o myweb cd myweb 然后就是业务代码的编辑,增删改查乱七八 ...
- 部署Dotnet Core应用到Kubernetes(一)
最近闲了点,写个大活:部署Dotnet应用到K8s. 写在前边的话 一直想完成这个主题.但这个主题实在太大了,各种拖延症的小宇宙不时爆发一下,结果就拖到了现在. 这个主题,会是一个系列.在这个 ...
- dotnet core 通过修改文件头的方式隐藏控制台窗口
原文:dotnet core 通过修改文件头的方式隐藏控制台窗口 在带界面的 dotnet core 程序运行的时候就会出现一个控制台窗口,本文告诉大家使用最简单方法去隐藏控制台窗口. 最近在使用 A ...
随机推荐
- git分支主干
~/Desktop/work/movies/movie(apps) $ git status //先查看是否有需要提交的东西# On branch appsnothing to commit (wo ...
- 方程的解_NOI导刊2010提高(01) 组合数
题目描述 佳佳碰到了一个难题,请你来帮忙解决. 对于不定方程a1+a2+…+ak-1+ak=g(x),其中k≥2且k∈N,x是正整数,g(x)=x^x mod 1000(即x^x除以1000的余数), ...
- STP-19-Port-Channel发现和配置
工程师在给一台交换机上的特定Port-Channel增加多个端口时,有一些配置参数必须相同,如下所示: 使用相同的速率和双工设置: 使用相同的操作模式(Trunk.Access.动态): 若不为T ...
- iOS获取手机型号、iOS获取当前app的名称和版本号
NSDictionary *infoDictionary = [[NSBundle mainBundle] infoDictionary]; CFShow(infoDictionary); // ap ...
- POJ1013 Counterfeit Dollar
题目来源:http://poj.org/problem?id=1013 题目大意:有12枚硬币,其中有一枚假币.所有钱币的外表都一样,所有真币的重量都一样,假币的重量与真币不同,但我们不知道假币的重量 ...
- 湖南省第十二届大学生计算机程序设计竞赛 problem A 2016
如果 a * b % 2016 == 0 如果a = 1 ,且 a * b % 2016 == 0 考虑一下a = 2017的时候 2017 * b = (2016 + 1) * b % 2016 = ...
- Spring自动注入有关的注解
Spring不但支持自己定义的@Autowired注解,还支持几个由JSR-250规范定义的注解,它们分别是@Resource.@PostConstruct以及@PreDestroy. 1,@Comp ...
- Windows下 bat调用TSql问题
一.建立sql文件 在sql管理工具中写好sql文件,并保证能够正常运行,之后用unique编码保存. 二.建立一个bat文件osql -U登录用户 -P密码 -S服务器 <sql文件.sql ...
- 深入理解jvm jdk1,7(1)
java 虚拟机管理的内存模型包含以下几个运行时数据区域: 程序计数器: 程序计数器是一块较小的内存空间,它可以看成当前线程执行的字节码的行号指示器.在虚拟机的概念模型里(仅是概念模型,各种虚拟机可能 ...
- 一、 Spring Cloud Eureka ,咱们先跑起来
一.Spring Cloud 简介 Spring Cloud 是一个基于Spring Boot 实现的微服务架构开发工具.是一个涉及到服务治理.分布式配置管理.负载均衡.服务容错.API网关.消息总线 ...