I'm trying to write a method that sends an email based on parameters, and it works completely on CentOS and OSX. However, the method doesn't work properly on Windows (even when recompiled on Windows) as well as some other Linux OS's - it throws a MessagingException. Does anyone have any ideas as to how I can fix this to work on Windows? Thanks!
private static void sendEmail(String towhom, String subject, String body) {
String host = "smtp.gmail.com", from = "myemail", pass = "mypassword";
Properties props = System.getProperties();
Scanner scan = new Scanner(System.in);
try {
props.put("mail.smtp.starttls.enable", "true");
props.put("mail.smtp.host", host);
props.put("mail.smtp.user", from);
props.put("mail.smtp.password", pass);
props.put("mail.smtp.port", "587");
props.put("mail.smtp.auth", "true");
Session session = Session.getDefaultInstance(props, null);
MimeMessage message = new MimeMessage(session);
message.setFrom(new InternetAddress(from));
InternetAddress toAddress = new InternetAddress(towhom);
message.addRecipient(Message.RecipientType.TO, toAddress);
message.setSubject(subject);
message.setText(body);
Transport transport = session.getTransport("smtp");
transport.connect(host, from, pass);
transport.sendMessage(message, message.getAllRecipients());
transport.close();
}
catch(AddressException e) {
System.out.println("Invalid Email Address.");
}
catch(MessagingException e) {
System.out.print("\nInvalid Email Address, please reenter it: ");
sendEmail(scan.nextLine(), subject, body);
}
}
So yes Avast Antivirus was causing the exception to be thrown when I was trying to send the mail. If anyone else has this problem who finds this page:
Open up Avast and click on the Security tab. Then click on the AntiVirus tab on the left. Under that, click Mail Shield and go to the settings. Untick "Scan outbound mail (SMTP)" and it will work like a charm.
There is no problem with your code. It looks good.
According to the JavaMail FAQ's. Following could be the problem -
There's a firewall or anti-virus program intercepting your request.
There's something wrong in your JDK installation preventing it from finding the certificates for the trusted certificate authorities.
You're running in an application server that has overridden the JDK's list of trusted certificate authorities.
If disabling your firewall and/or anti-virus does not solve the problem then you can try and reinstall the JDK and test.
Related
I try to call an external web service (not mine) from my GWT application working with App Engine.
I know it's impossible to do it from the client due to the SOP (Same Origin Policy) and RequestBuilder is not a solution on the server. I followed the tutorial on the web site and using java.net as well
Here is the client
AsyncCallback<CustomObject> callback = new AsyncCallback<CustomObjectCustomObject>() {
#Override
public void onFailure(Throwable caught) {
caught.printStackTrace();
}
#Override
public void onSuccess(CustomObject result) {
// code omitted
}
};
service.callMethod(aString, callback);
And this is the server
try {
String xmlRequest = "xmlToSend";
URL url = new URL("https://www.externalWebService.com");
HttpURLConnection conn = (HttpURLConnection)url.openConnection();
conn.setRequestMethod("POST");
conn.setAllowUserInteraction(false);
conn.setDoOutput(true);
conn.setRequestProperty("Content-Type","application/soap+xml");
conn.setRequestProperty( "Content-length", Integer.toString(xmlRequest.length()));
conn.setRequestProperty("charset", "utf-8");
conn.setConnectTimeout(10000);
OutputStream rawOutStream = conn.getOutputStream();
PrintWriter pw = new PrintWriter(rawOutStream);
pw.print(xmlRequest);
pw.flush();
pw.close();
if(conn.getResponseCode() != 200){
// Something...
}
I keep having the same error at conn.getResponseCode() :
java.lang.ClassCastException: com.google.appengine.repackaged.org.apache.http.message.BasicHttpRequest cannot be cast to com.google.appengine.repackaged.org.apache.http.client.methods.HttpUriRequest
Without making a real request, the remote service works well : it's able to serialize and return objects to the client. The issue is not linked to the communication between the client and the server, it's more like AppEngine doesn't support HttpURLConnection. But it should on the server (isn't it?)
Any thoughts would be hightly appreciated! Thanks in advance
Your problem has nothing to do with GWT: as long as you are running on the server, you can use any 'normal' Java and it will work unless AppEngine has restrictions.
It seems you have imported the repackaged version of Apache HttpClient in your class. You should not do that: download your own HttpClient .jar, add it to the dependencies and use that one.
AppEngine also has some issues with HttpClient. There's an adapter available here that fixes most of the issues.
Thanks #Marcelo, you were right!
Here is the solution I found.
I added httpcore.jar and httpclient.jar to my build path and wrote the code below for the server (the client is the same) :
String xmlRequest = "xmlToSend";
CloseableHttpClient httpclient = HttpClients.custom().build();
//RequestConfig requestConfig = RequestConfig.custom()
// .setConnectionRequestTimeout(10000)
// .build();
try {
ByteArrayOutputStream out = new ByteArrayOutputStream();
Writer writer = new OutputStreamWriter(out);
writer.write(xmlToSend);
writer.flush();
writer.close();
HttpPost request = new HttpPost("https://www.externalWebService.com/path");
request.setEntity(new ByteArrayEntity(out.toByteArray()));
//request.setConfig(requestConfig);
CloseableHttpResponse response = httpclient.execute(request);
if(response.getStatusLine().getStatusCode() == 200){
// retrieve content with a BufferReader
// from response.getEntity().getContent()
...
}
The code works and is up to date.
Edit
Here is the rest of the solution when using a proxy. Mine only deals with NTCredentials but otherwise UsernamePasswordCredentials can be used instead.
HttpHost proxy = new HttpHost("addresse.proxy.com", port);
CredentialsProvider credsProvider = new BasicCredentialsProvider();
credsProvider.setCredentials(
new AuthScope(proxy),
new NTCredentials(System.getProperty("user.name") + ":" + password));
RequestConfig requestConfig = RequestConfig.custom()
.setProxy(proxy)
.build();
CloseableHttpClient httpclient = HttpClients.custom()
.setDefaultCredentialsProvider(credsProvider)
.setDefaultRequestConfig(requestConfig)
.build();
Thanks again for your help, I really appreciated!
I am trying to retrieve a file from an ftp server with anonymous authentication using java.net.URLConnection.
try {
url = new URL("ftp://ftp2.sat.gob.mx/Certificados/FEA/000010/000002/02/03/05/00001000000202030500.cer");
URLConnection con = url.openConnection();
InputStream in = con.getInputStream();
ByteArrayOutputStream baos = new ByteArrayOutputStream();
byte[] buffer = new byte[4096];
int bytesRead;
while ((bytesRead = in.read(buffer)) >= 0)
{
baos.write(buffer, 0, bytesRead);
}
baos.flush();
arr = baos.toByteArray();
in.close();
} catch (Exception e) {
throw new Exception("Error SAT: " + e.getMessage());
}
The file i am trying to get is this, its in an anonymous authentication ftp site:
ftp://ftp2.sat.gob.mx/Certificados/FEA/000010/000002/02/03/05/00001000000202030500.cer
But every time I get this error:
Permission denied: Attempt to bind port without permission.
I am using GoogleAppEngine Java 1.7
Any kind of advise is welcome.
I'm not a Java guy, but I suspect you're trying to use "active" FTP, which is likely the default.
Active FTP works by binding to a port on the receiving computer (the client in this case) to which the sending server can connect to send the file; the port number is sent over in the get request. This doesn't work in many environments, e.g. NAT.
The usual solution is to use "passive" mode, which behaves more like HTTP and doesn't require any port binding. If there's a way in Java to twiddle that connection to use passive mode, it should bypass the permissions issue.
Most likely you have a non billing-enabled app, according to this post and this AppEngine Socket Java API documentation you just have to enable billing, if you have no budget set the limits to $0.
I am trying to read the mails from the exchange server 2010 , however sometimes the connection got established , but remaining times program gives below exception:
javax.mail.AuthenticationFailedException: LOGIN failed
The code is working fine with the exchange server 2007 . But from the time mailbox has been migrated to 2010, the program is behaving in this fashion only.
I have also tried with several options available on net, but nothing is working. I am using javamail-1.4.4 API version . Here is the piece of code through which I am just trying to connect to the mailbox .
public class ReadMail {
static Store store=null;
static String host="";
static String username="";
static String password="";
public static void main(String[] arg) throws Exception{
try{
Session session;
username = "username";
password = "password";
host = "hostname";
Properties props = System.getProperties();
props.setProperty("mail.smtp.auth","true");
session = Session.getInstance(props,
new ExchangeAuthenticator(username, password));
Store st = session.getStore("imaps");
st.connect(host,username, password);
System.out.println("Connected");
}
catch (Exception e){
e.printStackTrace(System.out);
}
}
}
public class ExchangeAuthenticator extends Authenticator {
String user;
String pw;
public ExchangeAuthenticator (String username, String password)
{
super();
this.user = username;
this.pw = password;
}
public PasswordAuthentication getPasswordAuthentication()
{
return new PasswordAuthentication(user, pw);
}
}
I also face same problem in my code i set two properties in my code
disable plain test and enable NTLM
props.setProperty("mail.imap.auth.plain.disable","true");
props.setProperty("mail.imap.starttls.enable", "true");
now my code able to connect with exchange server
read it
https://forums.oracle.com/forums/thread.jspa?threadID=1587688
Perhaps the configuration of the server has changed and it's no longer accepting your credentials, or no longer supporting any of the login methods that JavaMail supports.
Turn on session debugging and examine the protocol trace. It should provide some clues as to why it's failing.
You might also want to upgrade to JavaMail 1.4.5, which has built-in support for NTLM authentication, which you might need.
Even though your credentials are OK, the new server might not accept your login method. For instance, the new server might not allow "Plain" authentication.
The debugging info should show which authentication methods are accepted.
How to handle the login pop up window using Selenium Webdriver? I have attached the sample screen here. How can I enter/input Username and Password to this login pop up/alert window?
Thanks & Regards,
Use the approach where you send username and password in URL Request:
http://username:password#the-site.com
So just to make it more clear. The username is username password is password and the rest is usual URL of your test web
Works for me without needing any tweaks.
Sample Java code:
public static final String TEST_ENVIRONMENT = "the-site.com";
private WebDriver driver;
public void login(String uname, String pwd){
String URL = "http://" + uname + ":" + pwd + "#" + TEST_ENVIRONMENT;
driver.get(URL);
}
#Test
public void testLogin(){
driver = new FirefoxDriver();
login("Pavel", "UltraSecretPassword");
//Assert...
}
This should works with windows server 2012 and IE.
var alert = driver.SwitchTo().Alert();
alert.SetAuthenticationCredentials("username", "password");
alert.Accept();
This is very simple in WebDriver 3.0(As of now it is in Beta).
Alert alert = driver.switchTo().alert() ;
alert.authenticateUsing(new UserAndPassword(_user_name,_password));
driver.switchTo().defaultContent() ;
Hopefully this helps.
Now in 2020 Selenium 4 supports authenticating using Basic and Digest auth . Its using the CDP and currently only supports chromium-derived browsers
Example :
Java Example :
Webdriver driver = new ChromeDriver();
((HasAuthentication) driver).register(UsernameAndPassword.of("username", "pass"));
driver.get("http://sitewithauth");
Note : In Alpha-7 there is bug where it send username for both user/password. Need to wait for next release of selenium version as fix is available in trunk https://github.com/SeleniumHQ/selenium/commit/4917444886ba16a033a81a2a9676c9267c472894
Solution: Windows active directory authentication using Thread and Robot
I used Java Thread and Robot with Selenium webdriver to automate windows active directory authentication process of our website.
This logic worked fine in Firefox and Chrome but it didn't work in IE. For some reason IE kills the webdriver when authentication window pops up whereas Chrome and Firefox prevents the web driver from getting killed. I didn't try in other web browser such as Safari.
//...
//Note: this logic works in Chrome and Firefox. It did not work in IE and I did not try Safari.
//...
//import relevant packages here
public class TestDemo {
static WebDriver driver;
public static void main(String[] args) {
//setup web driver
System.setProperty("webdriver.chrome.driver", "path to your chromedriver.exe");
driver = new ChromeDriver();
//create new thread for interaction with windows authentication window
(new Thread(new LoginWindow())).start();
//open your url. this will prompt you for windows authentication
driver.get("your url");
//add test scripts below ...
driver.findElement(By.linkText("Home")).click();
//.....
//.....
}
//inner class for Login thread
public class LoginWindow implements Runnable {
#Override
public void run() {
try {
login();
} catch (Exception ex) {
System.out.println("Error in Login Thread: " + ex.getMessage());
}
}
public void login() throws Exception {
//wait - increase this wait period if required
Thread.sleep(5000);
//create robot for keyboard operations
Robot rb = new Robot();
//Enter user name by ctrl-v
StringSelection username = new StringSelection("username");
Toolkit.getDefaultToolkit().getSystemClipboard().setContents(username, null);
rb.keyPress(KeyEvent.VK_CONTROL);
rb.keyPress(KeyEvent.VK_V);
rb.keyRelease(KeyEvent.VK_V);
rb.keyRelease(KeyEvent.VK_CONTROL);
//tab to password entry field
rb.keyPress(KeyEvent.VK_TAB);
rb.keyRelease(KeyEvent.VK_TAB);
Thread.sleep(2000);
//Enter password by ctrl-v
StringSelection pwd = new StringSelection("password");
Toolkit.getDefaultToolkit().getSystemClipboard().setContents(pwd, null);
rb.keyPress(KeyEvent.VK_CONTROL);
rb.keyPress(KeyEvent.VK_V);
rb.keyRelease(KeyEvent.VK_V);
rb.keyRelease(KeyEvent.VK_CONTROL);
//press enter
rb.keyPress(KeyEvent.VK_ENTER);
rb.keyRelease(KeyEvent.VK_ENTER);
//wait
Thread.sleep(5000);
}
}
}
The easiest way to handle the Authentication Pop up is to enter the Credentials in Url Itself. For Example, I have Credentials like Username: admin and Password: admin:
WebDriver driver = new ChromeDriver();
driver.get("https://admin:admin#your website url");
This is a solution for Python based selenium, after going through the source code (here).
I found this 3 steps as useful.
obj = driver.switch_to.alert
obj.send_keys(keysToSend="username\ue004password")
obj.accept()
Here \ue004 is the value for TAB which you can find in Keys class in the source code.
I guess the same approach can be used in JAVA as well but not sure.
My usecase is:
Navigate to webapp.
Webapp detects I am not logged in, and redirects to an SSO site - different server!
SSO site (maybe on Jenkins) detects I am not logged into AD, and shows a login popup.
After you enter credentials, you are redirected back to webapp.
I am on later versions of Selenium 3, and the login popup is not detected with driver.switchTo().alert(); - results in NoAlertPresentException.
Just providing username:password in the URL is not propagated from step 1 to 2 above.
My workaround:
import org.apache.http.client.utils.URIBuilder;
driver.get(...webapp_location...);
wait.until(ExpectedConditions.urlContains(...sso_server...));
URIBuilder uri = null;
try {
uri = new URIBuilder(driver.getCurrentUrl());
} catch (URISyntaxException ex) {
ex.printStackTrace();
}
uri.setUserInfo(username, password);
driver.navigate().to(uri.toString());
You can use this Autoit script to handle the login popup:
WinWaitActive("Authentication Required","","10")
If WinExists("Authentication Required") Then
Send("username{TAB}")
Send("Password{Enter}")
EndIf'
I was getting windows security alert whenever my application was opening. to resolve this issue i used following procedure
import org.openqa.selenium.security.UserAndPassword;
UserAndPassword UP = new UserAndPassword("userName","Password");
driver.switchTo().alert().authenticateUsing(UP);
this resolved my issue of logging into application. I hope this might help who are all looking for authenticating windows security alert.
Simply switch to alert and use authenticateUsing to set usename and password and then comeback to parent window
Alert Windowalert = driver.switchTo().alert() ;
Windowalert.authenticateUsing(new UserAndPassword(_user_name,_password));
driver.switchTo().defaultContent() ;
1 way to handle this you can provide login details with url. e.g. if your url is "http://localhost:4040" and it's asking "Username" and "Password" on alert prompt message then you can pass baseurl as "http://username:password#localhost:4040".
Hope it works
In C# Selenium Web Driver I have managed to get it working with the following code:
var alert = TestDriver.SwitchTo().Alert();
alert.SendKeys(CurrentTestingConfiguration.Configuration.BasicAuthUser + Keys.Tab + CurrentTestingConfiguration.Configuration.BasicAuthPassword);
alert.Accept();
Although it seems similar, the following did not work with Firefox (Keys.Tab resets all the form and the password will be written within the user field):
alert.SendKeys(CurrentTestingConfiguration.Configuration.BasicAuthUser);
alert.SendKeys(Keys.Tab);
alert.SendKeys(CurrentTestingConfiguration.Configuration.BasicAuthPassword);
Also, I have tried the following solution which resulted in exception:
var alert = TestDriver.SwitchTo().Alert();
alert.SetAuthenticationCredentials(
CurrentTestingConfiguration.Configuration.BasicAuthUser,
CurrentTestingConfiguration.Configuration.BasicAuthPassword);
System.NotImplementedException: 'POST
/session/38146c7c-cd1a-42d8-9aa7-1ac6837e64f6/alert/credentials did
not match a known command'
Types of popups are defined in webdriver alerts: https://www.selenium.dev/documentation/webdriver/browser/alerts/
Here it is another type - authentication popup - eg generated by Weblogic and not seen by Selenium.
Being HTTPS the user/pass can't be put directly in the URL.
The solution is to create a browser extension: packed or unpacked.
Here is the code for unpacked and the packing procedure: https://qatestautomation.com/2019/11/11/handle-authentication-popup-in-chrome-with-selenium-webdriver-using-java/
In manifest.json instead of “https://ReplaceYourCompanyUrl“ put “<all_urls>”.
Unpacked can be used directly in Selenium:
#python:
co=webdriver.ChromeOptions()
co.add_argument("load-extension=ExtensionFolder")
<all_urls> is a match pattern
The flow for requests is in https://developer.chrome.com/docs/extensions/reference/webRequest/
We can also update browser setting to consider logged in user -
Internet Options-> Security -> Security Settings-> Select Automatic login with current user name and password.
The following Selenium-Webdriver Java code should work well to handle the alert/pop up up window:
driver.switchTo().alert();
//Selenium-WebDriver Java Code for entering Username & Password as below:
driver.findElement(By.id("userID")).sendKeys("userName");
driver.findElement(By.id("password")).sendKeys("myPassword");
driver.switchTo().alert().accept();
driver.switchTo().defaultContent();
I used IE, then create code like that and works after modification several code:
public class TestIEBrowser {
public static void main(String[] args) throws Exception {
//Set path of IEDriverServer.exe.
// Note : IEDriverServer.exe should be In D: drive.
System.setProperty("webdriver.ie.driver", "path /IEDriverServer.exe");
// Initialize InternetExplorerDriver Instance.
WebDriver driver = new InternetExplorerDriver();
// Load sample calc test URL.
driver.get("http://... /");
//Code to handle Basic Browser Authentication in Selenium.
Alert aa = driver.switchTo().alert();
Robot a = new Robot();
aa.sendKeys("host"+"\\"+"user");
a.keyPress(KeyEvent.VK_TAB);
a.keyRelease(KeyEvent.VK_TAB);
a.keyRelease(KeyEvent.VK_ADD);
setClipboardData("password");
a.keyPress(KeyEvent.VK_CONTROL);
a.keyPress(KeyEvent.VK_V);
a.keyRelease(KeyEvent.VK_V);
a.keyRelease(KeyEvent.VK_CONTROL);
//Thread.sleep(5000);
aa.accept();
}
private static void setClipboardData(String string) {
// TODO Auto-generated method stub
StringSelection stringSelection = new StringSelection(string); Toolkit.getDefaultToolkit().getSystemClipboard().setContents(stringSelection, null);
}
}
I'm trying to send a mail using the GoDaddy email host I have registered couple of days ago using Java mail api, however it turns out that its not that easy to implement,
and I am getting, this error:
Could not connect to SMTP host: smtpout.asia.secureserver.net, port: 80, response: -1
I have tried ports 3535, 465, 587, 25 but still get the same error. The same code below has been tested to work with sending out email using Gmail, with the addition of this code (which I have omitted in this case):
props.put("mail.smtp.socketFactory.class", "javax.net.ssl.SSLSocketFactory");
MailSender.java:
public class MailSender {
private static String HOST = "smtpout.asia.secureserver.net";
private static String PORT = "80";
public static void sendMail(final Mail mail) throws MailException {
EmailValidator validtor = new EmailValidator();
if (validtor.validate(mail.getReceipient())) {
Properties props = new Properties();
props.put("mail.smtp.host", HOST);
props.put("mail.smtp.socketFactory.port", PORT);
props.put("mail.smtp.auth", "true");
props.put("mail.smtp.port", PORT);
Session session = Session.getDefaultInstance(props,
new javax.mail.Authenticator() {
protected PasswordAuthentication getPasswordAuthentication() {
return new PasswordAuthentication(mail.getUsername(),mail.getPassword());
}
});
try {
Message message = new MimeMessage(session);
message.setFrom(new InternetAddress(mail.getSender()));
message.setRecipients(Message.RecipientType.TO,
InternetAddress.parse(mail.getReceipient()));
message.setSubject(mail.getSubject());
message.setText(mail.getBody());
Transport.send(message);
System.out.println("OK");
} catch (MessagingException e) {
throw new MailException(e.getMessage());
}
} else {
throw new MailException("Email address not valid.");
}
}
}
The Mail parameter in this class holds all other mail information, the username/password, sender and recipient email address string, which is tested to work with email clients like Outlook & Thunderbird.
Port 80 is used for HTTP.
Change it to 465 or 587.
(Consult the GoDaddy documentation for the correct port)
Apparently, the problem was not with Java mail api, but was with GoDaddy server, I have consulted their tech support and work fine now.