JavaFX e sua compatibilidade entre sistemas?

Ontem eu tava fazendo um programa muito simples a unica utilidade dele é listar nomes em um diretório e fiz em javaFX, bom para executar o programa precisa ter o javaFX instalado no pc eu nao queria depender ou ter que fazer a pessoa precisar baixa o javaFX para pode usar esse programinha então resolvi que para meu caso que eu iria empacotar o javaFX e todas as suas dependências em um .jar para isso usei a biblioteca shadowJar, e funcionou perfeitamente e tals mas percebi uma coisa quando eu compilava ele no windows e tentava rodar no linux nao funcionava e o mesmo vale para o inverso, abrindo os dois jar eu percebi que o do windows tinha .ddl e do linux .os eu queria saber como posso deixa isso compatível entre os dois sistemas? Um unico jar compilado em windows ou linux que funciona em ambos e obviamente mantendo isso do javaFX ja ser incluso

Existe distribuição de JDK tipo da BellSoft que vem incluso o JavaFX ( com versões até a ultima, tem a base do OpenJDK com HotSpot )
https://docs.bell-sw.com/liberica-jdk/11.0.11b10/general/install-guide/

Para rodar o jar em diferentes SO estando modularizado como o caso do JavaFX >= 9 precisa colocar dentro de um arquivo de lote ou chamar passando os parametros

Exemplo
No Java 8 com o JavaFX (nesse caso o JavaFX tambem esta dentro da JDK ou JRE)
java -jar Ensemble8.jar

No Java >=9 com JavaFX (nesse exemplo o JavaFX está separado)
java -Dprism.verbose=true --module-path /usr/bin/java/javafx/javafx-sdk-19.0.2.1/lib/ --add-modules javafx.controls,javafx.graphics,javafx.media,javafx.web -jar Ensemble8.jar

No Java >=9 (com a JavaFX incluso, Usando a JVM da BellSoft, mesmo modularizado )
java -jar Ensemble8.jar

Sem estar o JavaFX dentro da JDK é mais complicado mesmo, principalmente se tem versões compativeis mas diferentes em diretorios diferentes, tambem tem a opção de gerar uma versão especifica para o SO usando o jpackage

Outra opção para distribuição é o Open WebStart
Com ele voce pode configurar qual JDK baixar e quais modulos baixar na instalação

JavaFX é sim compativel em diferentes plataformas, mas os SO alteraram suas politicas de uso, uma delas foi proibir o uso de JVM principalmente nas lojas de aplicativos, então nesse caso tem que gerar nativo, porem…, a biblioteca JavaFX é a mesma e mantem toda a compatibilidade, nada de surpresinhas em diferentes SO (pelo menos essa é a proposta)

Então se desenvolver para Android por exemplo, será usada a biblioteca padrão do JavaFX e não a interna do Android.

1 curtida

Então cara embora seja um programa bem simples que so eu vou usar ainda pretendo usar javaFX para outras coisas e assim eu gosto de fazer aplicações, programas que nao dependem do externo ou seja eu gosto de trabalhar com javaFX só precisando da jvm e pronto por isso eu gosto de empacotar o javaFX no jar porque assim tudo que você precisa é da jvm e pronto nao precisa baixa javaFX separado e tals e eu tbm gosto de facilidade para usuário com isso eu quero dizer que mesmo que seja dificil para mim resolver o problema eu quero que o usuário tenha a facilidade entao a solução de usar outra jdk especial é Interresante mas nao serve porque imagine que alguem precisa usar meu programa ai ela tem que baixa outro java ainda uma versão especial, eu queria fazer um jar com tudo pronto nele o unico requisito externo sendo a jvm padrão e pronto.
Como falei para esse programa meu que é bem simples Ok mas para algumas coisas que eu penso nao é uma boa solução por causa desses motivos, e entao volta naquela problema porque eu acredito que o javaFX é multiplataforma porque tem 1 para cada sistema entao quando voce roda um jar em cada sistema o jar vai pegar esse javaFX agora se foce empacotou um javaFX no seu jar e seu jar usa ele voce perde essa compatibilidade por isso eu queria empacotar os dois javaFX digamos assim

Se quer facilitar para seus usuários é mais facil pensar em nativo usando jpackage ou OpenWebStart.

Todavia, entenda que os modulos trazem uma vantagem aquela idéia inicial de uma unica JVM.

Nos modulos, você empacota somente os modulos que sua aplicação vai usar e tambem uma JRE otimizada de acordo com a sua aplicação atraves do jlink

Entendo o que você quer, mas como Eu disse, as coisas mudaram independentemente da vontade do povo do Java.

Swing somente roda em diversos (SO)s porque tá tudo dentro da JVM ou JRE inclusive as coisas nativas.

1 curtida

Se o projeto é muito simples, pq não joga ele pra rodar na web?

Tentei ver se dava para criar um único JAR com as bibliotecas do Windows e Linux, mas não consegui achar.

No final eu acho que vc vai ter que fazer o seguinte:

  • Vc faz empacota para o Windows
  • Depois empcota para o Linux e qualquer outro sistema
  • Por último vc vai disponibilizar numa página de download todas as versões empacotadas.

Assim não tem problema algum pro usuário, pois é uma prática bastante comum.

O que eu fazia no passado com sistemas que dependiam de código nativo era empacotar os .dll e/ou .so nos zips/jars do sistema e durante a inicialização, antes de tudo, extrair as bibliotecas nativas e adicionar o diretório ao java.library.path.

No seu projeto vc está usando Gradle?

Sim

Então eu acho que o melhor jeito é vc usar este plugin:

Ele usa as ferramentas jlink e jpackage para criar um pacote personalizado contendo a sua aplicação e um JRE, permitindo que seus usuários a utilizem sem nem precisar instalar o Java nas máquinas deles.

E também dá para criar um instalador bonitinho, facilitando ainda mais a experiência.

Então vc poderia configurar o GitHub Actions (ou outra plataforma de CI/CD) para fazer os builds para Linux, Windows e Mac para vc.

Acredito que este seja o fluxo ideal atualmente.