Переопределение файла класса из библиотеки JAR в веб-приложении Java - PullRequest
10 голосов
/ 03 декабря 2011

В моем веб-приложении Java у меня есть следующие файлы:

/WEB-INF/classes/com/example/Foo.class
/WEB-INF/lib/example.jar <-- contains the class "com.example.Foo"

Будет ли использоваться класс, определенный в каталоге classes, вместо класса, определенного в example.jar?

Спасибо.

Ответы [ 2 ]

13 голосов
/ 03 декабря 2011

Ответ зависит от вашего контейнера, это зависит от контейнера. В общем, / WEB-INF / classes предпочтительнее, чем классы в файле jar в WEB-INF / lib.

Для Tomcat , порядок следующий:

Таким образом, с точки зрения загрузки веб-приложения, класса или ресурса выглядит в следующих репозиториях, в следующем порядке:

  1. Начальные классы вашей JVM
  2. Классы загрузчика классов системы
  3. / WEB-INF / классы вашего веб-приложения
  4. / WEB-INF / lib / *. Jar вашего веб-приложения
  5. Общие классы загрузчиков классов

Но если вы используете другой контейнер, вам нужно обратиться к документации для этого сервера.

7 голосов
/ 03 декабря 2011

Так что есть только один способ узнать. Я написал тест :)

├── example
│   ├── example.iml
│   ├── pom.xml
│   └── src
│       ├── main
│       │   └── java
│       │       └── test
│       │           ├── Bar.java
│       │           └── Foo.java
│       └── test
│           └── java
│               └── testexample
│                   └── TestFoo.java
├── pom.xml
├── test.iml
└── web
    ├── pom.xml
    ├── src
    │   ├── main
    │   │   └── java
    │   │       └── test
    │   │           └── Foo.java
    │   └── test
    │       └── java
    │           └── junittest
    │               └── TestFooInWeb.java
    └── web.iml

16 directories, 11 files

Я обнаружил, что при TestFoo.java печати

Hello from example.jar
Hello from example.jar

А для TestFooInWeb.java отпечатков

Hello from web app
Hello from web app

Оба теста имеют это в классе теста:

public class TestFooInWeb/TestFoo {
    @Test
    public void testHello() {
        System.out.println(new Foo().sayHello());
    }

    @Test
    public void testHelloFromBar() {
        new Bar().sayHelloForFoo();
    }
}

Так что все в конце я стою исправлено. Вы можете загружать совершенно другой класс, и все файлы Jar будут использовать этот новый класс. Это имеет смысл, потому что ClassLoader сначала будет смотреть на каталог классов. Я не уверен, согласен ли я с этим, потому что это звучит подозрительно, и я могу перезаписать классы безопасности.

...