我已经研究过我的困境,在这里和网络上,整合和修改我的项目中的东西,从我认为从配置和构建的角度来看是正确的,但问题仍然存在。
我的开发环境是NetBeans 8.0.2和8.1Beta,使用Glassfish 4.0作为我的应用服务器,并使用Maven作为构建管理器。我已经开发并构建了一个EJB库,它们安装在服务器上没有任何问题。我已经构建并部署了一个访问和使用EJB的NetBeans RCP应用程序。然后,我需要构建一个独立的命令行应用程序(可执行jar)来访问这些EJB以提供报告。该应用程序在NetBeans IDE中运行良好。独立的jar文件失败了,这就是它变得有趣的地方。 我的pom文件使用maven-jar-plugin和maven-assembly-plugin来构建jar文件,包括依赖项。由于这是一个远程应用程序,我有一个库,其中定义了EJB的远程接口。这是pom:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.lamtec</groupId>
<artifactId>ArclinReport</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>jar</packaging>
<dependencies>
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>MaterialsEJB</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.12</version>
</dependency>
<dependency>
<groupId>org.glassfish.appclient</groupId>
<artifactId>gf-client</artifactId>
<version>3.1.1</version>
<exclusions>
<exclusion>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.eclipse.persistence</groupId>
<artifactId>org.eclipse.persistence.core</artifactId>
<version>2.6.0</version>
</dependency>
<dependency>
<groupId>org.eclipse.persistence</groupId>
<artifactId>javax.persistence</artifactId>
<version>2.1.0</version>
</dependency>
<dependency>
<groupId>org.eclipse.persistence</groupId>
<artifactId>org.eclipse.persistence.jpa</artifactId>
<version>2.6.0</version>
</dependency>
<dependency>
<groupId>org.eclipse.persistence</groupId>
<artifactId>org.eclipse.persistence.antlr</artifactId>
<version>2.6.0</version>
</dependency>
<dependency>
<groupId>org.eclipse.persistence</groupId>
<artifactId>org.eclipse.persistence.jpa.modelgen</artifactId>
<version>2.4.2</version>
</dependency>
<dependency>
<groupId>org.eclipse.persistence</groupId>
<artifactId>org.eclipse.persistence.oracle</artifactId>
<version>2.6.0</version>
</dependency>
<dependency>
<groupId>org.jxls</groupId>
<artifactId>jxls</artifactId>
<version>2.2.5</version>
</dependency>
<dependency>
<groupId>org.jxls</groupId>
<artifactId>jxls-poi</artifactId>
<version>1.0.5</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<!-- Build an executable JAR -->
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>2.6</version>
<configuration>
<archive>
<manifest>
<addClasspath>true</addClasspath>
<classpathPrefix>lib/</classpathPrefix>
<mainClass>com.lamtec.arclinreport.data.ArclinReportGenerator</mainClass>
</manifest>
</archive>
</configuration>
</plugin>
<!-- <plugin>
<artifactId>maven-dependency-plugin</artifactId>
<version>2.10</version>
<executions>
<execution>
<id>unpack-dependencies</id>
<phase>install</phase>
<goals>
<goal>unpack-dependencies</goal>
</goals>
</execution>
</executions>
</plugin>
-->
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<version>2.5.5</version>
<configuration>
<archive>
<manifest>
<mainClass>com.lamtec.arclinreport.data.ArclinReportGenerator</mainClass>
</manifest>
</archive>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
</configuration>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
</properties>
</project>
这个pom将构建一个包含所有依赖项的jar文件。由于我执行的jndi查找是非标准的,我有一个位于src / main / resources目录中的jndi.properties文件(netbeans ide中这些类型的东西的标准)是这样的:
java.naming.factory.initial = com.sun.enterprise.naming.SerialInitContextFactory
java.naming.factory.url.pkgs = com.sun.enterprise.naming
java.naming.factory.state = com.sun.corba.ee.impl.presentation.rmi.JNDIStateFactoryImpl
#optional. Defaults to localhost. Only needed if web server is running
#on a different host than the appserver
org.omg.CORBA.ORBInitialHost = 10.20.10.52
#optional. Defaults to 3700. Only needed if target orb port is not 3700.
org.omg.CORBA.ORBInitialPort = 40198
第一个奇怪的问题是我在构建之后在最终的jar文件中找到的jndi.properties文件。它似乎是一个默认的jndi.properties文件,我找不到它的来源,我搜索了高低。第二个奇怪的是,我的jndi.properties文件没有进入最后的jar。这是最终jar中的jndi.properties文件:
#
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
#
# Copyright (c) 1997-2010 Oracle and/or its affiliates. All rights reserved.
#
# The contents of this file are subject to the terms of either the GNU
# General Public License Version 2 only ("GPL") or the Common Development
# and Distribution License("CDDL") (collectively, the "License"). You
# may not use this file except in compliance with the License. You can
# obtain a copy of the License at
# https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
# or packager/legal/LICENSE.txt. See the License for the specific
# language governing permissions and limitations under the License.
#
# When distributing the software, include this License Header Notice in each
# file and include the License file at packager/legal/LICENSE.txt.
#
# GPL Classpath Exception:
# Oracle designates this particular file as subject to the "Classpath"
# exception as provided by Oracle in the GPL Version 2 section of the License
# file that accompanied this code.
#
# Modifications:
# If applicable, add the following below the License Header, with the fields
# enclosed by brackets [] replaced by your own identifying information:
# "Portions Copyright [year] [name of copyright owner]"
#
# Contributor(s):
# If you wish your version of this file to be governed by only the CDDL or
# only the GPL Version 2, indicate your decision by adding "[Contributor]
# elects to include this software in this distribution under the [CDDL or GPL
# Version 2] license." If you don't indicate a single choice of license, a
# recipient has the option to distribute your version of this file under
# either the CDDL, the GPL Version 2 or to extend the choice of license to
# its licensees as provided above. However, if you add GPL Version 2 code
# and therefore, elected the GPL Version 2 license, then the option applies
# only if the new code is made subject to such option by the copyright
# holder.
#
java.naming.factory.initial=com.sun.enterprise.naming.impl.SerialInitContextFactory
java.naming.factory.url.pkgs=com.sun.enterprise.naming
# Required to add a javax.naming.spi.StateFactory for CosNaming that
# supports dynamic RMI-IIOP.
java.naming.factory.state=com.sun.corba.ee.impl.presentation.rmi.JNDIStateFactoryImpl
所以,第一个问题,对于Maven大师来说,为什么我的pom不能使构建过程包括我的jndi.properties?默认应该包括它,不是吗?哦,BTW,也是构建的jar文件,它不包含依赖项(因此不会使它成为“真正的”独立应用程序)包含正确的jndi.properties文件。所以我的假设是maven-assembly-plugin似乎不遵循标准的打包方案。
现在,关于我的最后一个问题:当我尝试使用java -jar ArclinReport-1.0-SNAPSHOT-jar-with-dependencies.jar运行jar文件时,出现错误:
Exception in thread "main" java.lang.NullPointerException
at com.sun.enterprise.naming.impl.SerialContext.<init>(SerialContext.java:276)
at com.sun.enterprise.naming.impl.SerialContext.<init>(SerialContext.java:335)
at com.sun.enterprise.naming.impl.SerialInitContextFactory.createInitialContext(SerialInitContextFactory.java:358)
at com.sun.enterprise.naming.impl.SerialInitContextFactory.getInitialContext(SerialInitContextFactory.java:353)
at javax.naming.spi.NamingManager.getInitialContext(NamingManager.java:684)
at javax.naming.InitialContext.getDefaultInitCtx(InitialContext.java:313)
at javax.naming.InitialContext.init(InitialContext.java:244)
at javax.naming.InitialContext.<init>(InitialContext.java:192)
at com.lamtec.arclinreport.data.EjbLookUp.init(EjbLookUp.java:45)
at com.lamtec.arclinreport.data.ArclinReportGenerator.main(ArclinReportGenerator.java:27)
EjbLookUp.java文件中第45行的错误是创建InitialContext并用于查找EJB的位置。我试过分离出新的InitialContext();呼叫,当我这样做时,就是报告错误的行。 java代码:
package com.lamtec.arclinreport.data;
import com.lamtec.materialsejb.ejb.MmrawrolFacadeRemote;
import java.util.Properties;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
*
* @author kpenrose
*/
public class EjbLookUp {
private static final Logger logger = LoggerFactory.getLogger(EjbLookUp.class.getName());
private MmrawrolFacadeRemote mmrawrolFacade;
public EjbLookUp() {
}
// @PostConstruct
public void init() {
Properties props = new Properties();
props.setProperty(Context.INITIAL_CONTEXT_FACTORY, "com.sun.enterprise.naming.SerialInitContextFactory");
// props.setProperty(Context.PROVIDER_URL, "iiop://10.20.10.52:40198");
props.setProperty("java.naming.factory.url.pkgs", "com.sun.enterprise.naming");
props.setProperty("java.naming.factory.state", "com.sun.corba.ee.impl.presentation.rmi.JNDIStateFactoryImpl");
props.setProperty("org.omg.CORBA.ORBInitialHost", "10.20.10.52");
props.setProperty("org.omg.CORBA.ORBInitialPort", "40198");
System.out.println("props" + props.toString());
// try {
// props.load(new FileInputStream(new File("src/main/resources/jndi.properties")));
// } catch (IOException ie) {
// System.out.println("Error reading file");
// }
try {
// InitialContext ctx = new InitialContext();
mmrawrolFacade = (MmrawrolFacadeRemote) new InitialContext().lookup("java:global/MaterialsEJB-1.0-SNAPSHOT/MmrawrolFacade");
} catch (NamingException ex) {
logger.info("Error with jndi lookup: {}", ex.getMessage());
}
}
public MmrawrolFacadeRemote getMmrawrolFacade() {
return mmrawrolFacade;
}
public void setMmrawrolFacade(MmrawrolFacadeRemote mmrawrolFacade) {
this.mmrawrolFacade = mmrawrolFacade;
}
}
因此,认为需要替换不正确的jndi.properties文件,我使用正确的jndi.properties文件更新jar文件,但这并不能解决问题。 无论我使用的是8.0.2还是8.1Beta的NetBeans,问题都是一样的。我已经尝试了maven-dependency-plugin来构建jar文件,但后来我遇到了签名jar等问题。 重申一下,NetBeans RCP应用程序和NetBeans IDE中的工作正常。在从独立应用程序获取InitialContext时,似乎缺少一些东西。哦,要清楚,我依赖于glassfish应用程序客户端所需的gf-client库。 任何人?感谢。