2016-05-24 9 views
2

MVCアーキテクチャをモデルにした簡単なWebアプリケーションを構築中です。私はHTML形式の小さなJSPページを持っています。フォームデータはサーブレットに転送され、サーブレットはControllerクラスに委譲されます。Java EEエラー:javax.enterprise.inject.UnsatisfiedResolutionException:Apiタイプ

フォームでsubmitをクリックすると、「UnsatisfiedResolutionException」によってHTTPステータス500 - エラーが表示されます。コンテナがコントローラを見つけることができないようですか?

Context.xmlファイルが自分のデータソースとして機能します。私はapache tomee webprofile 1.7.4を使用しています。

エラー:

type Exception report 

message Error instantiating servlet class a1.DispatcherServlet 

description The server encountered an internal error that prevented it from fulfilling this request. 

exception 

javax.servlet.ServletException: Error instantiating servlet class a1.DispatcherServlet 
    org.apache.tomee.catalina.OpenEJBValve.invoke(OpenEJBValve.java:44) 
    org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:103) 
    org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:956) 
    org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:436) 
    org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1078) 
    org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:625) 
    org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:318) 
    java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145) 
    java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615) 
    org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) 
    java.lang.Thread.run(Thread.java:745) 
root cause 

javax.enterprise.inject.UnsatisfiedResolutionException: Api type [a1.Controller] is not found with the qualifiers 
Qualifiers: [@javax.inject.Named(value=customerController)] 
for injection into Field Injection Point, field name : customerController, Bean Owner : [DispatcherServlet, Name:null, WebBeans Type:DEPENDENT, API Types:[java.io.Serializable,javax.servlet.GenericServlet,java.lang.Object,a1.DispatcherServlet,javax.servlet.Servlet,javax.servlet.http.HttpServlet,javax.servlet.ServletConfig], Qualifiers:[javax.enterprise.inject.Any,javax.enterprise.inject.Default]] 
    org.apache.webbeans.util.InjectionExceptionUtil.throwUnsatisfiedResolutionException(InjectionExceptionUtil.java:60) 
    org.apache.webbeans.container.InjectionResolver.getInjectionPointBean(InjectionResolver.java:250) 
    org.apache.webbeans.inject.AbstractInjectable.inject(AbstractInjectable.java:76) 
    org.apache.webbeans.inject.InjectableField.doInjection(InjectableField.java:65) 
    org.apache.webbeans.portable.InjectionTargetImpl.injectFields(InjectionTargetImpl.java:208) 
    org.apache.webbeans.portable.InjectionTargetImpl.inject(InjectionTargetImpl.java:194) 
    org.apache.webbeans.portable.InjectionTargetImpl.inject(InjectionTargetImpl.java:184) 
    org.apache.webbeans.component.AbstractOwbBean.create(AbstractOwbBean.java:125) 
    org.apache.openejb.core.WebContext.newInstance(WebContext.java:138) 
    org.apache.tomee.catalina.JavaeeInstanceManager.newInstance(JavaeeInstanceManager.java:46) 
    org.apache.tomee.catalina.JavaeeInstanceManager.newInstance(JavaeeInstanceManager.java:66) 
    org.apache.tomee.catalina.JavaeeInstanceManager.newInstance(JavaeeInstanceManager.java:61) 
    org.apache.tomee.catalina.OpenEJBValve.invoke(OpenEJBValve.java:44) 
    org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:103) 
    org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:956) 
    org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:436) 
    org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1078) 
    org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:625) 
    org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:318) 
    java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145) 
    java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615) 
    org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) 
    java.lang.Thread.run(Thread.java:745) 

DispatcherServlet.java:

package a1; 

/* Imports */ 

public class DispatcherServlet extends HttpServlet { 
    private static final long serialVersionUID = 1L; 

    @Inject 
    @Named("customerController") 
    private Controller customerController; 

    @Override 
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { 
     try { 
      String methodName = "addCustomer"; 

      Method method = customerController.getClass().getDeclaredMethod(methodName, HttpServletRequest.class); 
      method.setAccessible(true); 
      method.invoke(customerController, req); 

      req.getRequestDispatcher("/success.jsp").forward(req, resp); 
     } catch (SecurityException | IllegalArgumentException | NoSuchMethodException | IllegalAccessException | InvocationTargetException e) { 
      throw new RuntimeException(e); 
     } 
    } 
} 

CustomerController.java:

package a1; 

/* Imports */ 

@Named("customerController") 
public class CustomerController implements Controller { 

    @EJB 
    private CustomerService customerServiceImpl; 

    private void addCustomer(HttpServletRequest req) { 
     long cn1 = Long.parseLong(req.getParameter("form_cust_no")); 
     String n = req.getParameter("form_name"); 
     String s = req.getParameter("form_surname"); 

     try { 
      SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd"); 
      String formDate = req.getParameter("form_dob"); 
      java.util.Date dateUtil = sdf.parse(formDate); 
      java.sql.Date dateSql = new java.sql.Date(dateUtil.getTime()); 
      Customer customer = new Customer(cn1, n, s, dateSql); 

      customerServiceImpl.addCustomer(customer); 
     } catch (ParseException e) { 
      throw new RuntimeException(e); 
     } 
    } 
} 

のWeb.xml:

<?xml version="1.0" encoding="ISO-8859-1"?> 

<web-app xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee 
         http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" 
    version="3.0" metadata-complete="true"> 

    <servlet> 
     <servlet-name>dispatcher</servlet-name> 
     <servlet-class>a1.DispatcherServlet</servlet-class> 
    </servlet> 
    <servlet-mapping> 
     <servlet-name>dispatcher</servlet-name> 
     <url-pattern>/dispatcher/*</url-pattern> 
    </servlet-mapping> 

    <resource-ref> 
     <res-ref-name>jdbc/MyDataSource</res-ref-name> 
     <res-type>javax.sql.DataSource</res-type> 
     <res-auth>Container</res-auth> 
    </resource-ref> 
</web-app> 

のpersistence.xml:

<persistence xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="2.1" xsi:schemalocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_1.xsd"> 
    <persistence-unit name="Ejb1" transaction-type="JTA"> 
     <jta-data-source>jdbc/MyDataSource</jta-data-source> 

     <provider>org.hibernate.jpa.HibernatePersistenceProvider</provider> 
     <properties> 
      <property name="hibernate.connection.autocommit" value="false" /> 
     </properties> 
    </persistence-unit> 
</persistence> 

beans.xmlの:

<?xml version="1.0" encoding="UTF-8"?> 
<beans xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/beans_1_0.xsd"> 
</beans> 

のbuild.xml

<?xml version="1.0"?> 
<project name="h6" default="all" basedir="."> 
    <description>Homework 6</description> 

    <property file="build.properties" /> 

    <path id="master-classpath"> 
     <fileset dir="C:/myprograms/apache-tomee-webprofile-1.7.4/lib" /> 
     <pathelement path="/a1/" /> 
    </path> 

    <target name="clean" description="Clean class files and war files"> 
     <delete file="${targetdeploy.dir}${appname}.war" failonerror="false" /> 
     <delete file="${server.dir}/${appname}.war" failonerror="false" /> 
     <delete dir="${server.dir}/${appname}" failonerror="false" /> 
     <delete dir="/${classpath}/" failonerror="false" /> 
    </target> 

    <target name="compile" depends="clean" description="Compile all files into target"> 
     <javac srcdir="./src/main/java" destdir="./${classpath}" includeAntRuntime="false"> 
      <classpath refid="master-classpath" /> 
     </javac> 
    </target> 

    <target name="copy-classes" depends="compile" description="Copy classes from target into webapp"> 
     <copy todir="src/main/webapp/WEB-INF/classes/"> 
      <fileset dir="${classpath}" includes="**/*.class" /> 
      <fileset dir="${classpath}" includes="**/*.xml" /> 
     </copy> 
     <copy todir="src/main/webapp/WEB-INF/lib/"> 
      <fileset dir="${classpath}" includes="**/*.jar" /> 
     </copy> 
    </target> 

    <target name="generate-war" depends="copy-classes" description="Generate war file from webapp contents"> 
     <war destfile="./${targetdeploy.dir}${appname}.war" webxml="src/main/webapp/WEB-INF/web.xml"> 
      <fileset dir="src/main/webapp/"> 
       <include name="**/*.class" /> 
       <include name="**/*.jsp" /> 
       <include name="**/*.css" /> 
       <include name="**/*.html" /> 
       <include name="**/*.txt" /> 
       <include name="**/*.properties" /> 
       <include name="**/*.jar" /> 
       <include name="**/*.xml" /> 
      </fileset> 
     </war> 
    </target> 

    <target name="deploy-war" depends="generate-war" description="Copy war file into server"> 
     <copy todir="${server.dir}/"> 
      <fileset dir="${targetdeploy.dir}"> 
       <include name="*.war" /> 
      </fileset> 
     </copy> 
    </target> 

    <target name="extract-war" depends="deploy-war"> 
     <mkdir dir="${server.dir}/${appname}" /> 
     <unwar src="${server.dir}/${appname}.war" dest="${server.dir}/${appname}" /> 
    </target> 

    <target name="all" depends="extract-war" /> 
</project> 

Build.properties:

server.dir=C:/myprograms/apache-tomee-webprofile-1.7.4/webapps 
classpath=target/ide/classes 
targetdeploy.dir=target/deploy/ 
appname=h6 

フォルダ構造:

enter image description here

+0

質問に必要な情報が100%提供されています。なぜ投票したのか分かりませんが、あなたの質問のスタイルは信じられないほどです。 –

+0

@exabrial私はあまりにも多くの情報を含むかもしれないと心配していました。おそらくそれが下降声の理由でした。 – Irfaan

答えて

0

私はあなたがこの例で持っているような文字列に基づいて注入することはお勧めしませでしょう。あなたのコードは実際にはうまく動作するので、あなたのプロジェクトの何かが間違っていると、あなたが投稿しなかった問題を引き起こしています。これらの問題を回避するには、Stringベースの修飾子ではなくコンパイルされた修飾子を使用します。だからではなく、本の

@Named("customerController") 
public class CustomerController implements Controller { 

....

@Inject 
@Named("customerController") 
private Controller customerController; 

は、単純に次の操作を行います。(あなたがControllerの唯一の実装を持っている場合)

@Inject 
private Controller customerController; 

.. ..

@ApplicationScoped 
public class CustomerController implements Controller { 

これで完了です。 Controllerにコードを投稿していないか、Controllerの実装が複数ある場合は、 にはの実装が複数あると仮定すると、要件に応じてさまざまな処理方法があります。

最も簡単:

@Inject 
private CustomerController customerController; 

より柔軟:

@Qualifier 
@Retention(RUNTIME) 
@Target({FIELD, TYPE}) 
public @interface Customer { 
} 

...

@Inject 
@Customer 
private Controller customerController; 

...

@ApplicationScoped 
@Customer 
public class CustomerController implements Controller { 

はそれともだけで複数の実装を持っていますが、広いしばらくアプリケーションに一度の実装を変更する必要があります。

@ApplicationScoped 
@Default 
public class CustomerController implements Controller { 

... ...

@Inject 
private Controller customerController; 

@ApplicationScoped 
@Alternative 
public class AnotherCustomerController implements Controller { 

...

次に、代替を有効にする:

<beans ... > 
    <alternatives> 
     <class>a1.AnotherCustomerController</class> 
    </alternatives> 
</beans> 

幸運を祈る!さらに質問やフォローアップを返信してください。

PS:

あなたのコードは何の共有状態を持っていないように見えるので、私は@ApplicationScopedの代わり@Dependentを使用。

+0

ヒントをありがとう。 web.xmlで 'metadata-complete'を' false'に設定することは、この問題を解決したようです。しかし、私は、「Controller」の実装をさらに追加し、プロパティファイルを使用してフォームデータを関連コントローラにマップするつもりです。あなたが言及した注釈は、まだ使用できる可能性があります。 – Irfaan

+0

あなたはそれが分かったとうれしい! –