Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

539
Views
En Java9, ¿cómo puedo cargar reflexivamente una clase si no sé su módulo?

Supongamos que tengo una aplicación que, dado un nombre de paquete y una clase bien conocidos, necesito cargar esa clase de manera reflexiva e invocar algunos métodos desde ella. Digamos que esta clase está disponible en otro contenedor de Java (la "biblioteca").

Hasta ahora, antes de Java 9, dado que todas las clases en el classpath estaban disponibles, era sencillo lograrlo.

Sin embargo, con Java 9, si el "módulo" de la aplicación no requiere el paquete "biblioteca", no se puede acceder a la clase de biblioteca.

¿Cómo puedo lograr el mismo comportamiento usando frascos modularizados?

Ejemplo:

Esta es mi aplicación:

 // This is defined in ReflectionApp.jar // ReflectionApp // └── src // ├── module-info.java // └── org // └── reflection // └── app // └── ReflectionApp.java // package org.reflection.app; import java.lang.reflect.Method; public class ReflectionApp { private static final String PACKAGE = "org.reflection.lib"; private static final String CLASS = "ReflectiveClass"; private static final String METHOD = "doSomeWork"; public static void main(String[] args) throws Exception { // This will not work using java9 Class<?> klass = Class.forName(String.format("%s.%s", PACKAGE, CLASS)); Object obj = klass.getDeclaredConstructor().newInstance(); Method meth = klass.getDeclaredMethod(METHOD); meth.invoke(obj); } }

Y esta es mi biblioteca

 // This is defined in ReflectionLib.jar // ReflectionLib // └── src // ├── module-info.java // └── org // └── reflection // └── lib // └── ReflectiveClass.java // package org.reflection.lib; public class ReflectiveClass { public void doSomeWork() { System.out.println("::: Doing some work!"); } }

Por el momento, si trato de llamarlo así (suponiendo que todos los archivos estén creados y disponibles en el directorio lib):

java --module-path lib -m ReflectionApp/org.reflection.app.ReflectionApp

Luego obtengo una Exception in thread "main" java.lang.ClassNotFoundException: org.reflection.lib.ReflectiveClass

--- SOLUCIÓN ---

Gracias a @Nicolai pude hacerlo funcionar agregando el parámetro --add-modules al comando.

 ⇒ java --module-path lib --add-modules ReflectionLib -m ReflectionApp/org.reflection.app.ReflectionApp ::: Doing some work!
over 4 years ago · Santiago Trujillo
2 answers
Answer question

0

Hay muchas maneras de hacer que la reflexión funcione, pero ninguna de ellas es tan directa como la forma "simplemente funciona" antes del sistema de módulos. Permítanme reducirlos a su problema particular.

Pero antes de eso, debe asegurarse de que el módulo de la biblioteca realmente llegue al gráfico del módulo. Si el módulo inicial no lo requiere transitivamente, puede usar --add-modules library para agregarlo al gráfico.

Paquete exportado

Escribe que "si el 'módulo' de la aplicación no requiere el paquete 'biblioteca', la clase de biblioteca no es accesible". Suponiendo que quiso decir módulo en lugar de paquete, eso es cierto pero no se aplica aquí. La accesibilidad se basa en dos cosas:

  1. un borde de lectura entre los dos módulos
  2. el módulo accedido exportando los tipos accedidos

No escribiste nada con respecto a 2. pero si module library { exports org.reflection.lib; } , entonces eres libre de usar la reflexión. La razón es que el borde de lectura se agrega automáticamente cuando comienza a usar la API de reflexión.

Tipos no accesibles

Ahora se pone más interesante. Si el módulo de la biblioteca no exporta org.reflection.lib o si ReflectiveClass no fuera público, el enfoque anterior no funciona. En ese caso, tienes muchas opciones para elegir:

  • haga público el tipo y exporte el paquete (posiblemente solo al módulo de acceso)
  • abra el paquete (posiblemente solo al módulo de acceso) o el módulo
  • agregue opciones de línea de comando para lograr cualquiera de los anteriores

Para ver cómo se comparan, consulte este artículo sobre reflexión frente a encapsulación en Java 9 .

over 4 years ago · Santiago Trujillo Report

0

Si el primer módulo no depende del segundo módulo a través de la cláusula requires en module-info.java , entonces el segundo módulo no está en el cierre transitivo de las dependencias del primer módulo. Por lo tanto, el segundo módulo no es observable para el tiempo de ejecución y su reflejo falla. En este caso, puede agregar explícitamente su módulo al gráfico del módulo a través de la opción --add-modules :

 --add-modules <module-name>

En su caso <module-name> debe sustituirse por el nombre del módulo ReflectionLib .

over 4 years ago · Santiago Trujillo Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!