java.lang.ClassNotFoundException:となってしまった時の対応方法

# 事象 : java.lang.ClassNotFoundException: javax.servlet.jsp.jstl.core.Config
- 環境
    - CentOS Linux release 7.9.2009 (Core)
    - Apache Tomcat/8.0.21
    - Eclipse IDE for Enterprise Java Developers. Eclipse IDE for Enterprise Java Developers.

さっきまで動いていたのにぃEclipseのワークスペースを切り替えまくっていたらエラーが・・・

```bash
重大: Servlet.service() for servlet [FacesServlet] in context with path [] threw exception [javax/servlet/jsp/jstl/core/Config] with root cause
java.lang.ClassNotFoundException: javax.servlet.jsp.jstl.core.Config
    at java.net.URLClassLoader$1.run(URLClassLoader.java:366)
    at java.net.URLClassLoader$1.run(URLClassLoader.java:355)
    at java.security.AccessController.doPrivileged(Native Method)
...
```

## 原因 : 不明

### 対応 : Mavenビルド & Tomcatクリーン & プロジェクトクリーン
落ち着いて「Mavenビルド & Tomcatクリーン & プロジェクトクリーン」をしたら動いた・・・GlassFishか！

「jstlを追加する」という対応で治ることもある用だ。
参考 : [jsf - java.lang.ClassNotFoundException: javax.servlet.jsp.jstl.core.Config - Stack Overflow](https://stackoverflow.com/questions/15113628/java-lang-classnotfoundexception-javax-servlet-jsp-jstl-core-config)

# 事象 : java.lang.ClassNotFoundException: org.apache.commons.lang3.StringUtils
- 環境
    - CentOS Linux release 7.8.2003 (Core)
    - Eclipse IDE for Enterprise Java Developers.Version: 2020-03 (4.15.0)
        - Maven Integration for Eclipse 1.15.0
    - openjdk version "11.0.7" 2020-04-14 LTS
    - JSF 2.3.9
    - Payara Server 5.194

Mavenでライブラリを追加してコードで使ってからアプリケーションを実行してページを表示したらHTTPステータス500になった

```bash:Eclipseのコンソールのエラー
javax.el.ELException: /base.xhtml @20,53 rendered="#{!uploadBean.upload}": java.lang.NoClassDefFoundError: org/apache/commons/lang3/StringUtils
    at com.sun.faces.facelets.el.TagValueExpression.getValue(TagValueExpression.java:77)
    at javax.faces.component.ComponentStateHelper.eval(ComponentStateHelper.java:170)
...省略...
Caused by: javax.el.ELException: java.lang.NoClassDefFoundError: org/apache/commons/lang3/StringUtils
    at javax.el.BeanELResolver.getValue(BeanELResolver.java:304)
    at com.sun.faces.el.DemuxCompositeELResolver._getValue(DemuxCompositeELResolver.java:156)
...省略...
Caused by: java.lang.NoClassDefFoundError: org/apache/commons/lang3/StringUtils
    at brans.UploadBean.isUpload(UploadBean.java:30)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
...省略...
Caused by: java.lang.ClassNotFoundException: org.apache.commons.lang3.StringUtils
    at org.glassfish.web.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1687)
    at org.glassfish.web.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1528)
    ... 58 more
```

```xml:base.xhtml
...省略...
<!--ここで使っているメソッドでStringUtilsを使っている-->
      <ui:fragment rendered="#{!uploadBean.upload}">
...省略...
```

```java:UploadBean.java
import org.apache.commons.lang3.StringUtils;
...省略...
    public boolean isUpload() {
        // ここでStringUtilsを使っている
        return StringUtils.isBlank(fileName);
    }
...省略...
```

```xml:pom.xml
...省略...
<!-- Mavenでjarを取ってきている -->
<dependency>
    <groupId>org.apache.commons</groupId>
    <artifactId>commons-lang3</artifactId>
    <version>3.11</version>
</dependency>
...省略...
```

## 原因と対応 : 不明
jarにclassファイルはあった・・・何が問題？

```bash
$ jar -tf .m2/repository/org/apache/commons/commons-lang3/3.11/commons-lang3-3.11.jar | grep StringUtils
org/apache/commons/lang3/RandomStringUtils.class
org/apache/commons/lang3/StringUtils.class
```

### 試してダメだったこと1. 再度Mavenビルド & クリーン
1. `.m2/repository/org/apache/commons/commons-lang3`ディレクトリを削除
1. Mavenビルド
1. デプロイされているプロジェクトを削除してクリーン
1. プロジェクトをクリーン & Payaraに再度デプロイ

### 試してダメだったこと2. commons-langの2.6とcommons-lang3の3.1をpom.xmlに追加
- 参考
    - [java - NoClassDefFoundError: org/apache/commons/lang3/StringUtils - Stack Overflow](https://stackoverflow.com/questions/28504174/noclassdeffounderror-org-apache-commons-lang3-stringutils)
    - [Maven Repository: commons-lang » commons-lang » 2.6](https://mvnrepository.com/artifact/commons-lang/commons-lang/2.6)
    - [Maven Repository: org.apache.commons » commons-lang3 » 3.1](https://mvnrepository.com/artifact/org.apache.commons/commons-lang3/3.1)

1. pom.xmlに以下定義を追記
1. Mavenビルド
1. デプロイされているプロジェクトを削除してクリーン
1. プロジェクトをクリーン & Payaraに再度デプロイ

```xml
  <dependency>
    <groupId>commons-lang</groupId>
    <artifactId>commons-lang</artifactId>
    <version>2.6</version>
  </dependency>
  <dependency>
    <groupId>org.apache.commons</groupId>
    <artifactId>commons-lang3</artifactId>
    <version>3.1</version>
  </dependency>
```


# 事象 : java.lang.ClassNotFoundException: org.objectweb.jotm.TransactionFactoryImpl_Stub
- 環境
    - CentOS Linux release 7.6.1810 (Core)
    - Eclipse 2019-03 (4.11.0)
    - Java1.6.0_41
    - Apache Maven 3.2.5

EclipseでTomcatを起動したら怒られた

```bash:[Consol]タブのログ
2020-04-17 10:32:34.216 ERROR                                   Jotm.<init>:144 - Instanciation of TransactionFactory failed
java.rmi.StubNotFoundException: Stub class not found: org.objectweb.jotm.TransactionFactoryImpl_Stub; nested exception is: 
    java.lang.ClassNotFoundException: org.objectweb.jotm.TransactionFactoryImpl_Stub
...省略...
    at org.objectweb.jotm.Jotm.<init>(Jotm.java:140) ~[jotm-2.0.10.jar:"2.0.9"]
    at org.springframework.transaction.jta.JotmFactoryBean.<init>(JotmFactoryBean.java:95) ~[spring-dao-2.0.8.jar:2.0.8]
...省略...
Caused by: java.lang.ClassNotFoundException: org.objectweb.jotm.TransactionFactoryImpl_Stub
    at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1698) ~[catalina.jar:6.0.53]
    at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1544) ~[catalina.jar:6.0.53]
    at java.lang.Class.forName0(Native Method) ~[na:1.6.0_41]
    at java.lang.Class.forName(Class.java:274) ~[na:1.6.0_41]
    at sun.rmi.server.Util.createStub(Util.java:286) ~[na:1.6.0_41]
    ... 85 common frames omitted
```

ログに`jotm-2.0.10.jar`と表示されているが、プロジェクトのpom.xmlに定義しているのは`jotm-2.1.1.pom`なので不思議に思った。

```xml:プロジェクトのpom.xml
<dependency>
  <groupId>org.ow2.jotm</groupId>
  <artifactId>jotm</artifactId>
  <version>2.1.1</version>
  <type>pom</type>
  <exclusions>
...省略...
</dependency>
...省略...
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-dao</artifactId>
    <version>2.0.8</version>
</dependency>
...省略...
```

ログの`jotm-2.0.10.jar`の下に`spring-dao-2.0.8.jar`があるので`spring-dao-2.0.8.pom`を見てみると、「あった！」

```bash:spring-dao-2.0.8.pomを見てみる
$ cat ~/.m2/repository/org/springframework/2.0.8/spring-dao-2.0.8.pom
...省略...
<dependency>
  <groupId>jotm</groupId>
  <artifactId>jotm</artifactId>
  <version>2.0.10</version>
  <optional>true</optional>
</dependency>
...省略...
````

## 原因 : プロジェクトのpom.xmlで定義しているjarの依存関係の先にあるクラスがないから
`spring-dao-2.0.8.pom` が使う `jotm-2.0.10.jar` が使う `org.objectweb.jotm.TransactionFactoryImpl_Stub` がないことが原因

### 対応方法 : 依存関係の先にあるクラスを含むjarをpom.xmlに定義する

1. [JAR Search - findJAR.com](https://www.findjar.com/index.x)で、`org.objectweb.jotm.TransactionFactoryImpl_Stub`がなんていうjarに含まれるかを検索する
1. 検索で判明した`jotm-jrmp-stubs`を[Maven Repository: Search/Browse/Explore](http://mvnrepository.com/)で検索する
1. プロジェクトのpom.xmlに定義を追加する

```xml:プロジェクトのpom.xml
...省略...
<dependency>
    <groupId>jotm</groupId>
    <artifactId>jotm_jrmp_stubs</artifactId>
    <version>2.0.10</version>
</dependency>
...省略...
```

# 事象 : java.lang.ClassNotFoundException: org.jboss.util.NullArgumentException

- 環境
    - Windows10 Pro 64bit
    - GlassFish Server Open Source Edition  4.1  (build 13)
    - Java version 1.8.0_231
    - Eclipse Version: Oxygen.3a Release (4.7.3a)

GlassFishを起動しようとしたら怒られた

```text:エラーダイアログのメッセージ
cannot Deploy プロジェクト名
deploy is failing=Error occurred during deployment: Exception while loading the app : CDI deployment failure:org/jboss/util/NullArgumentException. Please see server.log for more details.
```
```log:server.log
[2019-11-13T17:39:04.980+0900] [glassfish 4.1] [SEVERE] [] [javax.enterprise.system.core] [tid: _ThreadID=48 _ThreadName=admin-listener(5)] [timeMillis: 1573634344980] [levelValue: 1000] [[
  Exception while loading the app : CDI deployment failure:org/jboss/util/NullArgumentException
java.lang.NoClassDefFoundError: org/jboss/util/NullArgumentException
    at java.lang.Class.getDeclaredMethods0(Native Method)
    at java.lang.Class.privateGetDeclaredMethods(Class.java:2615)
...省略...
Caused by: java.lang.ClassNotFoundException: org.jboss.util.NullArgumentException
    at org.glassfish.web.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1783)
    at org.glassfish.web.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1633)
...省略...
```

## 原因 : プロジェクトにないクラスを使っているから
理由あって何でもいいから例外を発生させたくて適当に補完で出た例外を書いたらプロジェクトには存在しない例外でした・・・。

```java
import org.jboss.util.NullArgumentException;
...省略...
                //                return hoge();
                throw new NullPointerException();
...省略...
```

### 対応 : プロジェクトにないクラスは削除する
「削除する」「入れる」「作る」のいずれかで対応します。