Error I am getting is:
java.util.NoSuchElementException while running junit test. Here is full error from console in eclipse:
java.util.NoSuchElementException
at java.base/java.util.ArrayList$Itr.next(ArrayList.java:970)
at java.base/java.util.Collections.max(Collections.java:713)
at io.cucumber.core.feature.FeatureParser.parseResource(FeatureParser.java:45)
at java.base/java.util.function.BiFunction.lambda$andThen$0(BiFunction.java:70)
at io.cucumber.core.resource.ResourceScanner.lambda$processResource$1(ResourceScanner.java:79)
at io.cucumber.core.resource.PathScanner$ResourceFileVisitor.visitFile(PathScanner.java:75)
at io.cucumber.core.resource.PathScanner$ResourceFileVisitor.visitFile(PathScanner.java:60)
at java.base/java.nio.file.Files.walkFileTree(Files.java:2811)
at io.cucumber.core.resource.PathScanner.findResourcesForPath(PathScanner.java:53)
at io.cucumber.core.resource.PathScanner.findResourcesForUri(PathScanner.java:31)
at io.cucumber.core.resource.ResourceScanner.findResourcesForUri(ResourceScanner.java:61)
at io.cucumber.core.resource.ResourceScanner.scanForResourcesUri(ResourceScanner.java:134)
at io.cucumber.core.runtime.FeaturePathFeatureSupplier.loadFeatures(FeaturePathFeatureSupplier.java:62)
at io.cucumber.core.runtime.FeaturePathFeatureSupplier.get(FeaturePathFeatureSupplier.java:45)
at io.cucumber.junit.Cucumber.<init>(Cucumber.java:156)
at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:77)
at java.base/jdk.internal.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
at java.base/java.lang.reflect.Constructor.newInstanceWithCaller(Constructor.java:499)
at java.base/java.lang.reflect.Constructor.newInstance(Constructor.java:480)
at org.junit.internal.builders.AnnotatedBuilder.buildRunner(AnnotatedBuilder.java:104)
at org.junit.internal.builders.AnnotatedBuilder.runnerForClass(AnnotatedBuilder.java:86)
at org.junit.runners.model.RunnerBuilder.safeRunnerForClass(RunnerBuilder.java:70)
at org.junit.internal.builders.AllDefaultPossibilitiesBuilder.runnerForClass(AllDefaultPossibilitiesBuilder.java:37)
at org.junit.runners.model.RunnerBuilder.safeRunnerForClass(RunnerBuilder.java:70)
at org.junit.internal.requests.ClassRequest.createRunner(ClassRequest.java:28)
at org.junit.internal.requests.MemoizingRequest.getRunner(MemoizingRequest.java:19)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestLoader.createUnfilteredTest(JUnit4TestLoader.java:90)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestLoader.createTest(JUnit4TestLoader.java:76)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestLoader.loadTests(JUnit4TestLoader.java:49)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:513)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:756)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:452)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:210)
Library I am using:
My Testrunner script is:
package TestRunner;
import org.junit.runner.RunWith;
import org.openqa.selenium.NoSuchElementException;
import io.cucumber.junit.Cucumber;
import io.cucumber.junit.CucumberOptions;
#RunWith(Cucumber.class)
#CucumberOptions(features="C:\\Users\\Ashok Kumar\\eclipse-workspace\\CucumberWithSelenium\\Features",glue={"StepDefinition"})
public class Runner {
}
My steps script:
package StepDefinition;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.NoSuchElementException;
//import io.cucumber.java.*;
import io.cucumber.java.en.Given;
import io.cucumber.java.en.Then;
import io.cucumber.java.en.When;
//import cucumber.api.junit.Cucumber;
public class Steps {
WebDriver driver = null;
#Given("^I am on Facebook login page$")
/*
public void goToFacebook() {
WebDriver driver = new ChromeDriver();
driver.get("https://www.facebook.com");
driver.manage().timeouts().pageLoadTimeout(30, TimeUnit.SECONDS);
} */
#Given("^Open the Chrome and launch the application$")
public void open_the_Chrome_and_launch_the_application() throws Throwable{
System.out.println("This Step open the Firefox and launch the application.");
}
#When("^Enter the Username and Password$")
public void enter_the_Username_and_Password() throws Throwable
{
System.out.println("This step enter the Username and Password on the login page.");
}
#Then("^Reset the credential$")
public void Reset_the_credential() throws Throwable
{
System.out.println("This step click on the Reset button.");
}
}
I have searched all previous posts in google on java.util.NoSuchElementException. But still I didn't come to webdriver as you have seen above. I did comment it as I have come across this error. I have tried even with WebDriver code above, still I am getting the error. Please help me. I am unable to edit java.base/java.util.ArrayList$Itr.next using next I have seen in google.
Thanks God. I found a solution or work around. Here is what I had done.
Had converted the project to Maven project.
I have mentioned latest dependencies
Here is my POM.
4.0.0
CucumberWithSelenium
CucumberWithSelenium
0.0.1-SNAPSHOT
src
maven-compiler-plugin
3.8.1
17
<dependency>
<groupId>io.cucumber</groupId>
<artifactId>cucumber-java</artifactId>
<version>7.2.3</version>
</dependency>
<dependency>
<groupId>io.cucumber</groupId>
<artifactId>cucumber-junit</artifactId>
<version>7.2.3</version>
</dependency>
<dependency>
<groupId>io.cucumber</groupId>
<artifactId>cucumber-jvm-deps</artifactId>
<version>1.0.6</version>
</dependency>
<dependency>
<groupId>net.masterthought</groupId>
<artifactId>cucumber-reporting</artifactId>
<version>1.0.0</version>
</dependency>
<dependency>
<groupId>io.cucumber</groupId>
<artifactId>gherkin</artifactId>
<version>22.0.0</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.13.2</version>
</dependency>
<dependency>
<groupId>org.seleniumhq.selenium</groupId>
<artifactId>selenium-java</artifactId>
<version>4.1.2</version>
</dependency>
<!-- https://mvnrepository.com/artifact/info.cukes/cucumber-picocontainer -->
<dependency>
<groupId>io.cucumber</groupId>
<artifactId>cucumber-picocontainer</artifactId>
<version>7.2.3</version>
</dependency>
</dependencies>
Related
I'm using Shiro 1.7.1 and Guice 4.2.3, below is the snippet of my POM file,
<properties>
<shiro.version>1.7.1</shiro.version>
<guice.version>4.2.3</guice.version>
</properties>
<dependencies>
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-web</artifactId>
<version>${shiro.version}</version>
</dependency>
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-guice</artifactId>
<version>${shiro.version}</version>
</dependency>
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-ehcache</artifactId>
<version>${shiro.version}</version>
</dependency>
<dependency>
<groupId>com.google.inject</groupId>
<artifactId>guice</artifactId>
<version>${guice.version}</version>
</dependency>
<dependency>
<groupId>com.google.inject.extensions</groupId>
<artifactId>guice-servlet</artifactId>
<version>${guice.version}</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.1.0</version>
<scope>provided</scope>
</dependency>
...
</dependencies>
I'm customizing Shiro's LogoutFilter by creating a new class,
package com.myshiro.myshiro;
import org.apache.shiro.web.filter.authc.LogoutFilter;
public class MyLogoutFilter extends LogoutFilter {
}
and bind org.apache.shiro.web.filter.authc.LogoutFilter to the above customized MyLogoutFilter,
package com.myshiro.myshiro;
public class MyShiroModule extends ShiroWebModule {
public MyShiroModule(ServletContext servletContext) {
super(servletContext);
}
protected void configureShiroWeb() {
try {
bindRealm().toConstructor(IniRealm.class.getConstructor(Ini.class));
} catch (NoSuchMethodException e) {
addError(e);
}
bind(org.apache.shiro.web.filter.authc.LogoutFilter.class).to(MyLogoutFilter.class).in(Scopes.SINGLETON);
addFilterChain("/logout", LOGOUT);
}
}
and I try to create the Guice injector in the unit test class like this,
public class MyShiroModuleTest {
#Mock
private ServletContext servletContext;
#Test
public void test() {
Guice.createInjector(new MyShiroModule(servletContext));
}
}
and it failed with the following errors,
1) Binding to null instances is not allowed. Use toProvider(Providers.of(null)) if this is your intended behaviour.
at org.apache.shiro.guice.web.ShiroWebModule.configureShiro(ShiroWebModule.java:136)
2) A binding to org.apache.shiro.web.filter.authc.LogoutFilter was already configured at com.myshiro.myshiro.MyShiroModule.configureShiroWeb(MyShiroModule.java:25).
at org.apache.shiro.guice.web.ShiroWebModule.setupFilterChainConfigs(ShiroWebModule.java:209)
From the second note above, it explained that the binding to org.apache.shiro.web.filter.authc.LogoutFilter is already configured in both MyShiroModule and ShiroWebModule. Do you have any idea of how to bind to my customized LogoutFilter?
This issue did not happened in Shiro 1.3.x.
My sample project is available here, you can see the error simply when you mvn clean install.
Sounds like your problem is related to Guice 4, and less about Shiro. Instead of re-using the same binding key, define a new one, something like:
bind(MyLogoutFilter.class).to(MyLogoutFilter.class).in(Scopes.SINGLETON);
addFilterChain("/logout", Key.get(MyLogoutFilter.class));
I created a web app using eclipse and (Jersey/JAX-RS). Although when i "run on server" from eclipse in glassfish everything is ok when I deploy the war file I produce either from maven install or from eclipse "export war file" it is deployed succesfully but when i try to access the same rest resources that work in the first option described above, they are not available "404" error.
This is my web.xml file :
<?xml version = "1.0" encoding = "UTF-8"?>
<web-app xmlns:xsi = "http://www.w3.org/2001/XMLSchema-instance"
xmlns = "http://java.sun.com/xml/ns/javaee"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
id = "WebApp_ID" version = "3.0">
<display-name>Rate it</display-name>
<welcome-file-list>
<welcome-file>login.html</welcome-file>
</welcome-file-list>
<listener>
<listener-class>
com.rateit.util.MyAppServletContextListener
</listener-class>
</listener>
<servlet>
<servlet-name>RateIt login services</servlet-name>
<servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class>
<init-param>
<param-name>jersey.config.server.provider.packages</param-name>
<param-value>com.rateit.login</param-value>
</init-param>
<init-param>
<param-name>jersey.config.server.provider.classnames</param-name>
<param-value>org.glassfish.jersey.media.multipart.MultiPartFeature</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>RateIt login services</servlet-name>
<url-pattern>/loginServices/*</url-pattern>
</servlet-mapping>
</web-app>
This is my pom file :
<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/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.gamechangerapps</groupId>
<artifactId>rateit</artifactId>
<packaging>war</packaging>
<version>0.0.1-SNAPSHOT</version>
<name>rateit Maven Webapp</name>
<url>http://maven.apache.org</url>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
</dependency>
<dependency>
<groupId>javax.ws.rs</groupId>
<artifactId>javax.ws.rs-api</artifactId>
<version>2.0.1</version>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.core</groupId>
<artifactId>jersey-client</artifactId>
<version>2.22.2</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.5</version>
</dependency>
<!-- https://mvnrepository.com/artifact/com.eclipsesource.minimal-json/minimal-json -->
<dependency>
<groupId>com.eclipsesource.minimal-json</groupId>
<artifactId>minimal-json</artifactId>
<version>0.9.4</version>
</dependency>
<!-- https://mvnrepository.com/artifact/log4j/log4j -->
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
</dependency>
<dependency>
<groupId>org.mongodb</groupId>
<artifactId>mongo-java-driver</artifactId>
<version>3.2.2</version>
</dependency>
<dependency>
<groupId>javax.mail</groupId>
<artifactId>mail</artifactId>
<version>1.4</version>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.media</groupId>
<artifactId>jersey-media-multipart</artifactId>
<version>2.19</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.1.0</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>2.8.0</version>
</dependency>
</dependencies>
<build>
<finalName>rateit</finalName>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<configuration>
<webXml>WebContent\WEB-INF\web.xml</webXml>
</configuration>
</plugin>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.7</source>
<target>1.7</target>
</configuration>
</plugin>
</plugins>
</build>
</project>
and this is my project structure :
project structure
This is LoginServices class
package com.rateit.login;
import java.io.InputStream;
import java.util.List;
import javax.servlet.ServletContext;
import javax.ws.rs.Consumes;
import javax.ws.rs.FormParam;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.QueryParam;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.Response.ResponseBuilder;
import javax.ws.rs.core.UriBuilder;
import org.apache.log4j.Logger;
import org.glassfish.jersey.media.multipart.FormDataContentDisposition;
import org.glassfish.jersey.media.multipart.FormDataParam;
import com.rateit.causecodes.LoginCodes;
import com.rateit.inbox.InboxServices;
import com.rateit.mailing.MailServices;
import com.rateit.property.Building;
import com.rateit.property.PropertyDao;
import com.rateit.rating.RatingQueue;
import com.rateit.util.BaseUriProvider;
import com.rateit.util.FileOperations;
import com.rateit.util.GlobalVariables;
import com.rateit.util.JobIdGenerator;
#Path("/Welcome")
public class LoginServices {
UserDao userDao = UserDao.getInstance();
MailServices mailBot = MailServices.getInstance();
FileOperations fileManager = new FileOperations();
PropertyDao propDao = PropertyDao.getInstance();
InboxServices inServ = new InboxServices();
String baseUri = BaseUriProvider.getStreamInstance().getBaseUri();
static Logger logger = Logger.getLogger(LoginServices.class);
#Context
private ServletContext context;
/**
* Service for Login purposes
*
* #FormParam String user email
* #FormParam String user password
*
* #return LoginCodes LOGIN_SUCCESFUL/LOGIN_FAILURE_INVALID_EMAIL/LOGIN_FAILURE_INVALID_PASSWORD/LOGIN_FAILURE_GENERIC
*
*/
#Path("/login")
#POST
#Consumes("application/x-www-form-urlencoded")
public Response login(#FormParam("email") String e, #FormParam("password") String p) {
ResponseBuilder builder = null;
// get new JobId for this operation
int jobId = JobIdGenerator.getStreamInstance().getJobId();
// Create the user object
User userInput = new User(e,p);
String loginCheck = LoginCodes.LOGIN_FAILURE_GENERIC.getDescription();
User userFromDB = userDao.getUser(userInput.getEmail());
logger.info("JobID="+jobId+" for user with email "+userInput.getEmail()+" this user "+userFromDB.getEmail()+" was found in DB");
// login successful
if(userInput.getEmail().equals(userFromDB.getEmail()) && userInput.getPassword().equals(userFromDB.getPassword())){
loginCheck = LoginCodes.LOGIN_SUCCESFUL.getDescription();
builder = Response.seeOther(UriBuilder.fromUri(baseUri+"/login.html").queryParam("user", userFromDB.getEmail()).queryParam("loginCheck", loginCheck).build());
}
// invalid mail
else if(!userInput.getEmail().equals(userFromDB.getEmail())){
loginCheck = LoginCodes.LOGIN_FAILURE_INVALID_EMAIL.getDescription();
builder = Response.seeOther(UriBuilder.fromUri(baseUri+"/login.html").queryParam("loginCheck", loginCheck).build());
}
// invalid password
else if(userInput.getEmail().equals(userFromDB.getEmail()) && !userInput.getPassword().equals(userFromDB.getPassword())){
loginCheck = LoginCodes.LOGIN_FAILURE_INVALID_PASSWORD.getDescription();
builder = Response.seeOther(UriBuilder.fromUri(baseUri+"/login.html").queryParam("loginCheck", loginCheck).build());
}
// both password and mail invalid
else{
builder = Response.seeOther(UriBuilder.fromUri(baseUri+"/login.html").queryParam("loginCheck", loginCheck).build());
}
logger.info("JobID="+jobId+" Login attempt for user "+e+" "+loginCheck);
return builder.build();
}
The problem is the follwing :
The following test can not hit the rest api
#Test
public void loginUserSuccessTest()
{
// Create a user and add him to the DB
User testUser = new User("testuser#rateit.com","1234");
mockDaoObject.addnewUser(testUser);
// Create a HTTP request
Client client = ClientBuilder.newClient();
//WebTarget target = client.target(baseUri+"/loginServices/Welcome/login");
WebTarget target = client.target("http://localhost:8080/rateit/loginServices/Welcome/login");
target.property(ClientProperties.FOLLOW_REDIRECTS, false);
Builder basicRequest = target.request();
// Create a form with the front end parameters
Form form = new Form();
form.param("email", testUser.getEmail());
form.param("password", testUser.getPassword());
// Send the request and get the response
Response response = basicRequest.post(Entity.form(form), Response.class);
// Delete the user
mockDaoObject.deleteUser(testUser);
// Check that the response is success
boolean correctCause = response.getLocation().toString().contains("loginCheck=User+logged+in+successfully");
boolean correctUser = response.getLocation().toString().contains("user=");
assertEquals(true, correctCause);
assertEquals(true, correctUser);
assertEquals(303, response.getStatus());
}
Any advice will be helpful
After some investigation i found the issue. The problem was that some dependencies were missing and also a configuration in eclipse.
I found the error by checking the logs/localhost.date log in tomcat.
There i found the following exception :
15-Oct-2019 23:04:16.492 INFO [http-nio-8080-exec-42] org.apache.catalina.core.ApplicationContext.log Marking servlet [RateIt login services] as unavailable
15-Oct-2019 23:04:16.493 SEVERE [http-nio-8080-exec-42] org.apache.catalina.core.StandardWrapperValve.invoke Allocate exception for servlet [RateIt login services]
java.lang.ClassNotFoundException: org.glassfish.jersey.servlet.ServletContainer
at org.apache.catalina.loader.WebappClassLoaderBase.loadClass(WebappClassLoaderBase.java:1365)
at org.apache.catalina.loader.WebappClassLoaderBase.loadClass(WebappClassLoaderBase.java:1188)
at org.apache.catalina.core.DefaultInstanceManager.loadClass(DefaultInstanceManager.java:540)
at org.apache.catalina.core.DefaultInstanceManager.loadClassMaybePrivileged(DefaultInstanceManager.java:521)
at org.apache.catalina.core.DefaultInstanceManager.newInstance(DefaultInstanceManager.java:150)
at org.apache.catalina.core.StandardWrapper.loadServlet(StandardWrapper.java:1042)
at org.apache.catalina.core.StandardWrapper.allocate(StandardWrapper.java:761)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:135)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:96)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:526)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:139)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92)
at org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:678)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:74)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:343)
at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:408)
at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:66)
at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:861)
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1579)
at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
at java.lang.Thread.run(Unknown Source)
Based on this error i fixed the deployment issue with the 3 following steps :
I added the following dependencies in my pom.xml file
org.glassfish.jersey.containers
jersey-container-servlet
2.19
org.glassfish.jersey.core
jersey-server
2.19
I added the maven dependencies in WEB-INF/lib folder through eclipse
MyProject->Properties->Deployment Assembly->Add(Maven Dependencies:source and WEB-INF/lib:Deploy Path
I created the war file through export in eclipse and not through maven task
I'm trying to get the name of the current cucumber scenario.
I'm using JUnit 4.10. When I add the #Before without any arguments then the method is successfully called. However if I include the argument Scenario then I get:
cucumber.runtime.CucumberException: Can't invoke
stepDefinitions.beforeScenarios(Scenario)
import cucumber.annotation.Before;
import gherkin.formatter.model.Scenario;
public class stepDefinitions {
public Scenario scenario = null;
#Before
public void beforeScenarios(Scenario scenario) {
System.out.println("Method called");
}
...
Any ideas what I'm doing wrong?
I'm updated my pom.xml with:
<dependency>
<groupId>org.seleniumhq.selenium</groupId>
<artifactId>selenium-java</artifactId>
<version>3.141.5</version>
</dependency>
<dependency>
<groupId>io.cucumber</groupId>
<artifactId>cucumber-java</artifactId>
<version>4.3.1</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.cucumber</groupId>
<artifactId>cucumber-junit</artifactId>
<version>4.3.1</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
Below are right API to be imported.
#Before - import cucumber.api.java.Before;
Scenario - import cucumber.api.Scenario;
I'm attempting to follow the basic examples on quarkus.io regarding using Vert.x. While attempting to use RxJava instead of the Axle API, I get a runtime error:
Error handling 24416339-00a4-4898-8373-b5d905b39179-2, org.jboss.resteasy.spi.UnhandledException: java.lang.NoClassDefFoundError: Could not initialize class io.vertx.reactivex.ext.web.client.WebClient
My code for this class is as follows:
package io.blah.accountadminservice.client;
import javax.annotation.PostConstruct;
import javax.enterprise.context.ApplicationScoped;
import javax.inject.Inject;
import org.eclipse.microprofile.config.inject.ConfigProperty;
//import io.vertx.axle.core.Vertx;
//import io.vertx.axle.ext.web.client.WebClient;
import io.vertx.reactivex.core.Vertx;
import io.vertx.reactivex.ext.web.client.WebClient;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
#ApplicationScoped
public class VaultClient {
private static final Logger LOGGER = LoggerFactory.getLogger(VaultClient.class);
#Inject
Vertx vertx;
private WebClient client;
private String vaultToken;
#ConfigProperty(name = "vault.host")
private String vaultHost;
#ConfigProperty(name = "vault.port")
private String vaultPort;
#ConfigProperty(name = "vault.loginPath")
private String vaultLoginPath;
#PostConstruct
void initialize() {
this.client = WebClient.create(vertx); // this kills it
}
public void getVaultToken() {
}
}
When following the tutorial using the Axel API, I can build a web client. As soon switch to reactivex, these failures start happening.
My dependencies are:
<dependencies>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-resteasy</artifactId>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
<version>${mockito.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-junit-jupiter</artifactId>
<version>${mockito.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-junit5</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.rest-assured</groupId>
<artifactId>rest-assured</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-vertx</artifactId>
</dependency>
<dependency>
<groupId>io.vertx</groupId>
<artifactId>vertx-rx-java2</artifactId>
<version>${vertx-version}</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
</dependency>
</dependencies>
vertx-version is set to 3.7.1 at the moment. Side note: I've noticed when using the rxjava2 import, it's not possible to import io.vertx.ext.web.client.WebClientOptions; I don't know if that's supposed to work or not.
You need to add the following dependency in your pom.xml file:
<dependency>
<groupId>io.vertx</groupId>
<artifactId>vertx-web-client</artifactId>
<version>3.7.1</version>
</dependency>
The version must match the version used in Quarkus.
I'm creating a web service with Jersey and Jetty Embedded with no web.xml file. It is very simple, It receive a binary file by a POST from a HTML form. It seems I didn't register the MultiPart Feature properly because When I try to use it with HTML form I get this error :
*
WARNING: No injection source found for a parameter of type public
javax.ws.rs.core.Response
org.multipart.demo.ReceiveFile.postMsg(java.io.InputStream,org.glassfish.jersey.media.multipart.FormDataContentDisposition)
throws java.lang.Exception at index 0. 2016-02-09
21:49:59.916:WARN:/:qtp1364335809-16: unavailable
org.glassfish.jersey.server.model.ModelValidationException: Validation
of the application resource model has failed during application
initialization.|[[FATAL] No injection source found for a parameter of
type public javax.ws.rs.core.Response
org.multipart.demo.ReceiveFile.postMsg(java.io.InputStream,org.glassfish.jersey.media.multipart.FormDataContentDisposition)
throws java.lang.Exception at index 0.;
source='ResourceMethod{httpMethod=POST,
consumedTypes=[multipart/form-data], producedTypes=[text/plain],
suspended=false, suspendTimeout=0,
I was looking for the solution for weeks, I have read all question related to this error on StackOverflow, for instance:
MULTIPART_FORM_DATA: No injection source found for a parameter of type public javax.ws.rs.core.Response
Jersey 2 injection source for multipart formdata
They didn't help me because Im not using web.xml
I have 3 classes
- ReceiveFile.class (try to receive the POST)
- resourceConfig.class (try to register the MultiPart feature)
- JettyServer.class (create server instance)
ReceiveFile.class
package org.multipart.demo;
import java.io.InputStream;
import javax.ws.rs.ApplicationPath;
import javax.ws.rs.Consumes;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import org.glassfish.jersey.media.multipart.FormDataContentDisposition;
import org.glassfish.jersey.media.multipart.FormDataParam;
#Path("/resources")
public class ReceiveFile
{
#POST
#Path("/fileUpload")
#Produces("text/plain")
#Consumes(MediaType.MULTIPART_FORM_DATA)
public Response postMsg (
#FormDataParam("file") InputStream stream,
#FormDataParam("file") FormDataContentDisposition fileDetail) throws Exception {
Response.Status respStatus = Response.Status.OK;
return Response.status(respStatus).build();
}
}
resourceConfig.class
package org.multipart.demo;
import java.util.HashSet;
import java.util.Set;
import javax.ws.rs.ApplicationPath;
import javax.ws.rs.core.Application;
import org.glassfish.jersey.media.multipart.MultiPart;
import org.glassfish.jersey.media.multipart.MultiPartFeature;
import org.glassfish.jersey.server.ResourceConfig;
/**
* Registers the components to be used by the JAX-RS application
*
*/
#ApplicationPath("/resources/fileUpload")
public class resourceConfig extends ResourceConfig {
/**
* Register JAX-RS application components.
*/
public resourceConfig(){
register(ReceiveFile.class);
register(JettyServer.class);
register(MultiPartFeature.class);
//packages("org.glassfish.jersey.media", "com.mypackage.providers");
}
}
JettyServer.class
package org.multipart.demo;
import org.eclipse.jetty.server.Handler;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.server.handler.DefaultHandler;
import org.eclipse.jetty.server.handler.HandlerList;
import org.eclipse.jetty.server.handler.ResourceHandler;
import org.eclipse.jetty.servlet.ServletContextHandler;
import org.eclipse.jetty.servlet.ServletHolder;
import org.glassfish.jersey.media.multipart.MultiPartFeature;
import org.glassfish.jersey.server.ResourceConfig;
import org.glassfish.jersey.server.ServerProperties;
public class JettyServer
{
// private static final Logger LOGGER = Logger.getLogger(UploadFile.class.getName());
public static void main(String[] args) throws Exception
{
ResourceConfig config = new ResourceConfig();
config.packages("org.multipart.demo");
Server jettyServer = new Server(8080);
ResourceHandler resource_handler = new ResourceHandler();
// Configure the ResourceHandler. Setting the resource base indicates where the files should be served out of.
// In this example it is the current directory but it can be configured to anything that the jvm has access to.
resource_handler.setDirectoriesListed(true);
resource_handler.setWelcomeFiles(new String[]{ "./index.html" , "./html/FileUpload.html" });
resource_handler.setResourceBase(".");
//Jersey ServletContextHandler
final ResourceConfig resourceConfig = new ResourceConfig(ReceiveFile.class);
resourceConfig.register(MultiPartFeature.class);
ServletContextHandler servletContextHandler = new ServletContextHandler(ServletContextHandler.SESSIONS);
ServletHolder jerseyServlet = servletContextHandler.addServlet(org.glassfish.jersey.servlet.ServletContainer.class, "/*" );
jerseyServlet.setInitParameter(ServerProperties.PROVIDER_PACKAGES, "org.multipart.demo");
// Add the ResourceHandler to the server.
HandlerList handlers = new HandlerList();
handlers.setHandlers(new Handler[] { resource_handler, servletContextHandler, new DefaultHandler() });
jettyServer.setHandler(handlers);
try {
jettyServer.start();
jettyServer.join();
} finally {
jettyServer.destroy();
}
}
}
the pom.xml
<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>org</groupId>
<artifactId>multipart.demo</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>multipart.demo</name>
<url>http://maven.apache.org</url>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-server</artifactId>
<version>9.2.3.v20140905</version>
</dependency>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-servlet</artifactId>
<version>9.2.3.v20140905</version>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.core</groupId>
<artifactId>jersey-server</artifactId>
<version>2.7</version>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.containers</groupId>
<artifactId>jersey-container-servlet-core</artifactId>
<version>2.7</version>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.containers</groupId>
<artifactId>jersey-container-jetty-http</artifactId>
<version>2.7</version>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.media</groupId>
<artifactId>jersey-media-moxy</artifactId>
<version>2.7</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>3.8.1</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.media</groupId>
<artifactId>jersey-media-multipart</artifactId>
<version>2.7</version>
</dependency>
<dependency>
<groupId>org.jvnet.mimepull</groupId>
<artifactId>mimepull</artifactId>
<version>1.9.6</version>
</dependency>
</dependencies>
</project>
Thanks in advance!
I See three different ResourceConfigs in your codebase, but none of them are actually used for the application. So the MultiPartFeature is never register, which is what is causing the error. You have a few options on how to use a ResourceConfig in your case.
You can instantiate the ServletContainer, passing in the ResourceConfig instance. Unfortunately, there is no ServletContextHolder#addServlet(Servlet) method, but there is a ServletContextHolder#addServlet(ServletHolder) method, so we need to wrap the ServletContainer in a ServletHolder
ServletHolder jerseyServlet = new ServletHolder(new ServletContainer(resourceConfig));
servletContextHolder.addServlet(jerseyServlet, "/*");
With the above option, you can use a local instance or a subclass, but if you only have a subclass, like your first bit of code, then you add a servlet init param, that specifies the ResourceConfig subclass.
ServletContextHandler servletContextHandler = new ServletContextHandler(ServletContextHandler.SESSIONS);
ServletHolder jerseyServlet = servletContextHandler.addServlet(org.glassfish.jersey.servlet.ServletContainer.class, "/*" );
jerseyServlet.setInitParameter(ServerProperties.PROVIDER_PACKAGES, "org.multipart.demo");
jerseyServlet.setInitParameter(ServletProperties.JAXRS_APPLICATION_CLASS, resourceConfig.class.getCanonicalName());
Notice the last call where I set the application class name.
Without using a ResourceConfig, you could just register the MulitPartFeature with an init param
jerseyServlet.setInitParameter(ServerProperties.PROVIDER_CLASSNAMES, MultiPartFeature.class.getCanonicalName());