在.Net中使用Java代碼?

前言

你沒有看錯,我確實在.Net6的項目中在編寫java,我都using java了,算不算在寫java那?

using com.microsoft.sqlserver.jdbc;
using java.sql;

並且編輯器還帶提示的功能

這一切都是藉助IKVM來實現的,或許有些人還聽說過使用IKVM的CLI命令來轉換jar包,比如使用Bing搜索:ikvm轉換jar包爲dll ,但是這個過程我是沒有經歷的,現在的使用方法更省事了

IKVM是什麼?

從GitHub摘抄說明:IKVM 是 Microsoft .NET 平臺的 Java 實現。它可用於快速輕鬆地:

  • 在 .NET Framework 或 .NET Core 上執行已編譯的 Java 代碼(字節碼)
  • 將字節碼轉換爲 .NET 程序集,以在 .NET 項目中直接訪問其 API

無需將源代碼移植到 .NET 即可完成這些任務。

GitHub地址:https://github.com/ikvmnet/ikvm

插播資訊

這裏插播一個看到的資訊,沒想到吧,中間居然夾帶私貨

都夾帶私貨了,那發個福利吧,地址放這裏吧:http://www.loongnix.cn/zh/api/dotnet/

用法

直接引用jar包

例如我們有一個netjar.jar包想將其引入到項目中,那麼我們可以在項目中創建一個jar的文件號,然後將netjar.jar文件放進去,然後修改項目文件

<Project Sdk="Microsoft.NET.Sdk">

    <PropertyGroup>
        <OutputType>Exe</OutputType>
        <TargetFramework>net6.0</TargetFramework>
        <ImplicitUsings>enable</ImplicitUsings>
        <Nullable>enable</Nullable>
    </PropertyGroup>

    <ItemGroup>
        <PackageReference Include="IKVM" Version="8.2.1" />
    </ItemGroup>

    <ItemGroup>
        <IkvmReference Include="jar/netjar.jar" >
            <AssemblyName>netjar</AssemblyName>
            <AssemblyVersion>1.0.0.4</AssemblyVersion>
        </IkvmReference>
    </ItemGroup>

</Project>

.csproj 中添加 IkvmReference , 再添加 Include 爲 jar/netjar.jar,並指定 AssemblyName 編譯後的 就是 netjar.dll ,AssemblyVersion 必須是 1.0.0.0 這種 4位數的版本號會給dll加上版本信息

IkvmReference的說明:https://github.com/ikvmnet/ikvm#attributes-and-elements

Maven源引用

推薦一個maven源給跟我一樣不會java的.Net開發者:https://mvnrepository.com/

項目中可以使用阿里雲的源:https://maven.aliyun.com/nexus/content/groups/public/

對比直接引用的方法,我們需要多安裝一個IKVM.Maven.Sdk的Nuget包,默認是有一個Maven源的,然後我們只需要修改.csproj項目文件進行配置MavenReference即可

<Project Sdk="Microsoft.NET.Sdk">

    <PropertyGroup>
        <OutputType>Exe</OutputType>
        <TargetFramework>net6.0</TargetFramework>
        <ImplicitUsings>enable</ImplicitUsings>
        <Nullable>enable</Nullable>
    </PropertyGroup>

    <ItemGroup>
        <PackageReference Include="IKVM" Version="8.7.1"/>
        <PackageReference Include="IKVM.Maven.Sdk" Version="1.6.1"/>
    </ItemGroup>

    <ItemGroup>
        <MavenReference Include="mssql-jdbc">
            <groupId>com.microsoft.sqlserver</groupId>
            <artifactId>mssql-jdbc</artifactId>
            <version>12.4.2.jre8</version>
        </MavenReference>

        <!-- <MavenReference Include="com.microsoft.sqlserver:mssql-jdbc" Version="12.4.2.jre8" />-->
    </ItemGroup>

</Project>

使用說明:https://github.com/ikvmnet/ikvm-maven#readme

其中MavenReference內容可以參考上面的maven源搜索出來的內容,比如:https://mvnrepository.com/artifact/com.microsoft.sqlserver/mssql-jdbc/12.4.1.jre8

設置自定義源

默認已經包含了源,也可以通過修改項目文件來設置自定義源,這裏我設置了阿里雲的源:https://maven.aliyun.com/nexus/content/groups/public/

<PropertyGroup>
    <OutputType>Exe</OutputType>
    <TargetFramework>net6.0</TargetFramework>
    <ImplicitUsings>enable</ImplicitUsings>
    <Nullable>enable</Nullable>

    <MavenDefaultRepositories Condition="'$(MavenDefaultRepositories)' == '' ">central=https://maven.aliyun.com/nexus/content/groups/public/</MavenDefaultRepositories>
    <MavenRepositories Condition=" '$(MavenRepositories)' == '' ">$(MavenDefaultRepositories);$(MavenAdditionalRepositories)</MavenRepositories>
</PropertyGroup>

操作示例

使用hutool序列化對象

下面演示調用java序列化的jar包來序列化(僅爲了演示效果),新建項目(此處我使用的是.Net6框架的項目),引用nuget包

<ItemGroup>
	<PackageReference Include="IKVM" Version="8.6.4" />
	<PackageReference Include="IKVM.Maven.Sdk" Version="1.5.5" />
</ItemGroup>

引用mvaen的包,修改項目文件如下

<Project Sdk="Microsoft.NET.Sdk">

	<PropertyGroup>
		<OutputType>Exe</OutputType>
		<TargetFramework>net6.0</TargetFramework>
		<ImplicitUsings>enable</ImplicitUsings>

		<MavenDefaultRepositories Condition="'$(MavenDefaultRepositories)' == '' ">central=https://maven.aliyun.com/nexus/content/groups/public/</MavenDefaultRepositories>
		<MavenRepositories Condition=" '$(MavenRepositories)' == '' ">$(MavenDefaultRepositories);$(MavenAdditionalRepositories)</MavenRepositories>
	</PropertyGroup>

	<ItemGroup>
		<PackageReference Include="IKVM" Version="8.6.4" />
		<PackageReference Include="IKVM.Maven.Sdk" Version="1.5.5" />
	</ItemGroup>


	<ItemGroup>
		<MavenReference Include="cn.hutool">
			<groupId>cn.hutool</groupId>
			<artifactId>hutool-all</artifactId>
			<version>5.6.6</version>
		</MavenReference>
	</ItemGroup>
    
</Project>

序列化對象

using cn.hutool.json;

var userInfo = new UserInfo { UserName = "admin", Password = "123456" };

var result = JSONUtil.toJsonStr(userInfo);
Console.WriteLine(result);

public class UserInfo
{
    /// <summary>
    /// 用戶名
    /// </summary>
    public string UserName;

    /// <summary>
    /// 密碼
    /// </summary>
    public string Password;
}

使用jdbc連接sqlserver2008

該示例是當時連接sqlserver2008一直報錯(數據庫版本太低了),java組那邊說他們連接不報錯,所以想操作試試搞的

新建一個.Net6的控制檯項目,然後引用nuget包(IKVM.Maven.Sdk是使用maven源用到的,直接引入jar包可以不安裝)

<ItemGroup>
    <PackageReference Include="IKVM" Version="8.7.1"/>
    <PackageReference Include="IKVM.Maven.Sdk" Version="1.6.1"/>
</ItemGroup>

這個時候就需要找一個連接數據庫的包,經過搜索後可以使用mssql-jdbc(也可以採用直接下載jar包放到項目目錄內的方法,不使用maven),那麼可以引入一下

<ItemGroup>
    <MavenReference Include="mssql-jdbc">
        <groupId>com.microsoft.sqlserver</groupId>
        <artifactId>mssql-jdbc</artifactId>
        <version>12.4.2.jre8</version>
    </MavenReference>

    <!--簡化寫法-->
    <!--<MavenReference Include="com.microsoft.sqlserver:mssql-jdbc" Version="12.4.2.jre8" />-->
</ItemGroup>

這時候如果項目生成不報錯了,那麼說明包等下載好、引用好了,開始編寫代碼,代碼雖然簡單,但是還是花費了一番功夫的

try
{
    var url = "jdbc:sqlserver://192.168.1.50:1433;DatabaseName=manage;Encrypt=false";
    var userName = "sa";
    var pwd = "admin123";
    DriverManager.registerDriver(new SQLServerDriver());
    var connection = DriverManager.getConnection(url, userName, pwd);
    var stmt = connection.createStatement();
    var rs = stmt.executeQuery("select @@version");
    while (rs.next())
    {
        Console.WriteLine(rs.getString(1));
    }

    Console.WriteLine("conn success");
}
catch (Exception ex)
{
    Console.WriteLine($"message:{ex.Message} stackTrace:{ex.StackTrace}");
}

經過我的瞎蒙以及查閱資料終於寫出來了上面查詢數據庫版本號的代碼,然後啓動項目查看輸出

測試一下容器部署,選中項目右鍵新建dockerfile文件如下(默認生成的)

FROM mcr.microsoft.com/dotnet/runtime:6.0 AS base
WORKDIR /app

FROM mcr.microsoft.com/dotnet/sdk:6.0 AS build
WORKDIR /src
COPY ["JavaConsoleApp/JavaConsoleApp.csproj", "JavaConsoleApp/"]
RUN dotnet restore "JavaConsoleApp/JavaConsoleApp.csproj"
COPY . .
WORKDIR "/src/JavaConsoleApp"
RUN dotnet build "JavaConsoleApp.csproj" -c Release -o /app/build

FROM build AS publish
RUN dotnet publish "JavaConsoleApp.csproj" -c Release -o /app/publish /p:UseAppHost=false

FROM base AS final
WORKDIR /app
COPY --from=publish /app/publish .
ENTRYPOINT ["dotnet", "JavaConsoleApp.dll"]

雖有警告,但是可以正常連接

這裏不得不說,他這組件要求還怪寬鬆,看過我上個文章的人就知道,我使用.Net組件連接sqlserver2008(甲方的數據庫,版本低還不能升級)還需要再dockefile中配置其它。

參考資料

maven文檔:https://github.com/ikvmnet/ikvm-maven

java操作數據庫:https://blog.csdn.net/qq_37917691/article/details/108262286

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章