Взаимодействие Java и Powershell - PullRequest
0 голосов
/ 31 января 2019

Предположим, что я хотел создать командлет Powershell на языке, отличном от Microsoft, в данном случае Java.

Очевидно, что это было бы простой задачей, например, в C #, но я не нашел никакой документации, показывающейкак (или даже подтверждает, если это возможно) интегрировать другие языки.

Я не имею в виду вызов исполняемых файлов Java из Powershell (java -jar Thing.jar или аналогичного), я хотел бы, чтобы он вел себя идентично "нативному"«Командлет Powershell - конвейерная обработка, получение / установка свойств и т. Д. - вся Java-сущность должна быть скрыта от powershell.

Итак: существует ли какой-либо слой / библиотеки / другой метод shim для представления кода Java каккомандлет PowerShell?

1 Ответ

0 голосов
/ 04 февраля 2019

Я думаю, что лучшим вариантом в вашем случае будет IKVM.Этот инструмент преобразует байт-код Java в байт-код CLR, поэтому, в основном, если у вас есть файл jar или класс, вы можете преобразовать его в dll, а затем добавить его в свой скрипт powershell (или код C #).Они уже конвертировали стандартную библиотеку Java, поэтому вам просто нужно попытаться конвертировать ваш jar.Нет гарантии, что это сработает, особенно с некоторыми новыми библиотеками, но шансы хорошие.Мне удалось преобразовать несколько драйверов jdbc и использовать их в powershell

https://www.ikvm.net/

Ниже приведен пример (подключение к базе данных Oracle):

# Download an extract IKVM to any folder
# cd C:\temp\ikvm\bin\
# convert jar to dll with ikvmc: ikvmc -target:library C:\jdbc\ojdbc6.jar


Add-Type -Path "C:\temp\ikvm\bin\ojdbc6.dll"
Add-Type -Path "C:\temp\ikvm\bin\IKVM.OPenJDK.Jdbc.dll"
Add-Type -Path "C:\temp\ikvm\bin\IKVM.OPenJDK.Core.dll"

$url = "jdbc:oracle:thin:@localhost:1521/someServiceName"
$driver = [oracle.jdbc.driver.OracleDriver]::new()
$props = [java.util.Properties]::new()
$props.setProperty("user", "someUser")
$props.setProperty("password", "somePassword")
$conn = $driver.connect($url, $props) 
$cmd = $conn.createStatement()

$r = $cmd.executeQuery("select * from all_tables where rownum < 20")
Write-Host "column count: $($r.getMetaData().getColumnCount())"

while($r.next()){

$row = foreach($c in 1..20){ $r.getString($c)}
Write-Host ($row -join "|")
}

Другой вариантэто использовать JVM API.Похоже, единственный бесплатный инструмент для этого - Jni4net .Он преобразует ваши файлы jar в прокси (dll), которые вы можете использовать в своем проекте .net для взаимодействия с JVM.Таким образом, вам нужно установить Java, чтобы он работал.Я мог создавать их примеры приложений, но не мог сгенерировать прокси для любого jdbc, с которым работал.Вы можете дать ему шанс, но я думаю, что он гораздо менее надежен, чем первый вариант.Прежде всего, загрузите двоичные файлы, а затем следуйте инструкции для генерации прокси: https://github.com/jni4net/jni4net/wiki/Generating-Proxies

Если не работает вышеперечисленное, чем исследовать Jython, Groovy и т. Д.

Кроме того, создайте оболочкудля «java -jar myJar ...» это не так уж плохо для меня.Если ваше Java-приложение печатает результаты в стандартный вывод, не должно быть проблем с интеграцией его с командлетами и использованием всех необходимых синтаксических символов PS.Ниже приведен пример переноса этого jdbc tool в командлет:

function Invoke-Jdbc { param(
  $java="Java" # or path to java exe 
, $format="EXCEL"
, $driver = "C:\jdbc\jdbcsql.zip"
, $dbtype, $hostname, $port, $db, $user, $password, $query
)

$data = &$java -jar $driver -f $format -m $dbtype -host $hostname -port $port -d $db -U $user -P $password $query
Write-Output -NoEnumerate ($data | ConvertFrom-Csv -Delimiter "`t" | Out-DataTable)

}


$oracle = @{ 
 dbtype = "oracle"
 hostname = "localhost"
 port = "1521"
 db = "ServiceNameOrSID"
 user = "user"
 password = "password"
 query = "select owner, table_name from all_tables"
}

$dt = Invoke-JDBC @oracle
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...