Standalone JBoss EJB Client application - how to get JNDI connection - "distinct name" - ejb

There is a plethora of frustratingly incorrect (better description - "close but no cigar") information concerning remote access to JBoss EJBs from a standalone application. I've been beating my head against this wall for over a day with no success.
I'm trying to port an EJB from WebLogic to JBoss, which is called by a standalone application running on another server.
I've been here, here, and several other places chasing down various "solutions" to my problem without success. I've tried reading the official documentation which wants me to install a "quickstart" based on Maven, which may or may not fit my situation, and which so far I have decided not to pursue. (My project is not built with Maven, it uses Gradle, but I am reasonably certain that I've managed to get all the right dependencies deployed).
I have a stateful EJB deployed in a WAR inside an EAR (previous implementation of deploying it simply in a WAR did not help matters).
I configure the client thusly:
public InitialContext createInitialContext() throws NamingException {
Properties prop = new Properties();
prop.put(Context.URL_PKG_PREFIXES, "org.jboss.ejb.client.naming");
prop.put(Context.INITIAL_CONTEXT_FACTORY,
"org.jboss.naming.remote.client.InitialContextFactory");
prop.put(Context.PROVIDER_URL, purl);
prop.put(Context.SECURITY_PRINCIPAL, "myusername");
prop.put(Context.SECURITY_CREDENTIALS, "mypassword");
prop.put("jboss.naming.client.ejb.context", false);
return new InitialContext(prop);
}
public void closeContext(Context context) throws NamingException {
if (context != null) {
context.close();
}
}
private String getJndiName(
String prefix,
String appName,
String moduleName,
String distinctName,
String beanName,
Class viewClass,
boolean stateful)
{
StringBuilder builder = new StringBuilder();
if (prefix != null && prefix.length() > 0) {
builder.append(prefix).append(':');
}
builder.append(appName)
.append('/')
.append(moduleName)
.append('/')
.append(distinctName)
.append('/')
.append(beanName).append('!')
.append(viewClass.getName());
if (stateful) {
builder.append("?stateful");
}
return builder.toString();
}
public Object lookup(Context context) throws NamingException {
final String prefix = "ejb";
final String appName = "myearname";
final String moduleName = "mywarname";
final String distinctName = "";
final String beanName = "MyBean";
final Class viewClass = MyBeanInterface.class;
String jndi = getJndiName(prefix, appName, moduleName, distinctName, beanName, viewClass, true);
return context.lookup(jndi);
}
Note that no "distinct name" is provided as none is needed. "distinct name" is supposed to be optional:
All of this gets invoked by:
MyBeanInterface sstatus = null;
try {
ctx = createInitialContext();
sstatus = (MyBeanInterface) lookup(ctx);
} catch (Exception ex) {
...
}
When this code is invoked, the following error message is produced:
Caused by: java.lang.IllegalStateException: EJBCLIENT000024: No EJB receiver available for handling [appName:SockTransport, moduleName:SockTransport, distinctName:] combination
at org.jboss.ejb.client.EJBClientContext.requireEJBReceiver(EJBClientContext.java:873) ~[ttjd.jar:?]
at org.jboss.ejb.client.EJBClient.createSessionWithPossibleRetries(EJBClient.java:222) ~[ttjd.jar:?]
at org.jboss.ejb.client.EJBClient.createSession(EJBClient.java:202) ~[ttjd.jar:?]
at org.jboss.ejb.client.naming.ejb.EjbNamingContext.doCreateProxy(EjbNamingContext.java:227) ~[ttjd.jar:?]
at org.jboss.ejb.client.naming.ejb.EjbNamingContext.createEjbProxy(EjbNamingContext.java:204) ~[ttjd.jar:?]
Using the above code, the JNDI name I am supplying is
ejb:myearname/mywarname//MyBean!com.whatever.my.package.MyBeanInterface. Note the double slash caused by the missing distinctName. I can and have rejiggered this code to produce instead ejb:myearname/mywarname/MyBean!com.whatever.my.package.MyBeanInterface and this makes no difference.
Frankly, I think this error message is a red herring. I suspect that there is some other problem with my setup that is not being caught and breaking on this interface. I don't think the distinct name or lack thereof has anything to do with the problem. I think that's simply how they log the object that can't be looked up.
Before I go down the path of figuring out how to add a useless "distinct name" in a probably vain attempt to keep JBOSS happy, can someone venture a guess as to what the real problem may be?
UPDATE:
The suggestions of #Steve_C are quite illuminating but I still have not gotten them to work. He left a few points out of the initial context creation:
Context.URL_PKG_PREFIXES
Context.INITIAL_CONTEXT_FACTORY
"jboss.naming.client.ejb.context"
but these were mentioned in the resource he cited - very handy by the way.
So I added these and my createInitialContext method now looks like this:
public InitialContext createInitialContext() throws NamingException {
Properties prop = new Properties();
prop.put(Context.URL_PKG_PREFIXES, "org.jboss.ejb.client.naming");
prop.put(Context.INITIAL_CONTEXT_FACTORY,
"org.jboss.naming.remote.client.InitialContextFactory");
prop.put(Context.PROVIDER_URL, "http-remoting://{server-ip}:{server-port});
prop.put("jboss.naming.client.ejb.context", true);
return new InitialContext(prop);
}
Why PROVIDER_URL is necessary when I've already supplied server-ip and server-port in the jboss-ejb-client.properties file remains mysterious, but it makes a difference.
With these three items added to my initial context environment, now I get a different error message (EJBCLIENT000025 instead of EJBCLIENT000024):
java.lang.IllegalStateException: EJBCLIENT000025: No EJB receiver available for handling [appName:SockTransport, moduleName:SockTransport, distinctName:] combination for invocation context org.jboss.ejb.client.EJBClientInvocationContext#67f639d3
at org.jboss.ejb.client.EJBClientContext.requireEJBReceiver(EJBClientContext.java:798) ~[ttjd.jar:?]
at org.jboss.ejb.client.ReceiverInterceptor.handleInvocation(ReceiverInterceptor.java:128) ~[ttjd.jar:?]
at org.jboss.ejb.client.EJBClientInvocationContext.sendRequest(EJBClientInvocationContext.java:186) ~[ttjd.jar:?]
at org.jboss.ejb.client.EJBInvocationHandler.sendRequestWithPossibleRetries(EJBInvocationHandler.java:255) ~[ttjd.jar:?]
at org.jboss.ejb.client.EJBInvocationHandler.doInvoke(EJBInvocationHandler.java:200) ~[ttjd.jar:?]
at org.jboss.ejb.client.EJBInvocationHandler.doInvoke(EJBInvocationHandler.java:183) ~[ttjd.jar:?]
at org.jboss.ejb.client.EJBInvocationHandler.invoke(EJBInvocationHandler.java:146) ~[ttjd.jar:?]
at com.sun.proxy.$Proxy20.create(Unknown Source) ~[?:?]
I suppose this counts as progress, but I'm finding this more difficult than it needs to be. I wonder if these new properties need to be in the properties file, but the official documentation pretty clearly says they don't.

The most flexible WildFly/JBossEAP remote EJB lookup and invocation can be done as follows:
Create a jboss-ejb-client.properties file which must be on the client classpath:
remote.connectionprovider.create.options.org.xnio.Options.SSL_ENABLED=false
remote.connections=default
remote.connection.default.host=<ip of jboss eap host>
remote.connection.default.port = 8080
remote.connection.default.connect.options.org.xnio.Options.SASL_POLICY_NOANONYMOUS=false
The EJBCLIENT000024: No EJB receiver available for handling error message is a symptom of a missing jboss-ejb-client.properties file.
Create an InitialContext:
Properties jndiProps = new Properties();
jndiProps.put(Context.URL_PKG_PREFIXES, "org.jboss.ejb.client.naming");
Context ctx = new InitialContext(jndiProps);
Note that no other properties are required.
Lookup the bean and call it:
ServiceLogic beanRemoteInterface = (ServiceLogic) ctx.lookup("ejb:/WhizBangSessionEJB/WhizBangSessionEJB!com.whatever.hostinterface.ServiceLogic?stateful");
String bar = beanRemoteInterface.sayHello();
System.out.println("Remote Foo bean returned " + bar);
Note the ?stateful on the end of the JNDI name that is required for stateful EJBs.
Output:
Jan 11, 2017 11:07:46 PM org.jboss.ejb.client.EJBClient <clinit>
INFO: JBoss EJB Client version 2.1.4.Final
Jan 11, 2017 11:07:46 PM org.xnio.Xnio <clinit>
INFO: XNIO version 3.4.0.Final
Jan 11, 2017 11:07:46 PM org.xnio.nio.NioXnio <clinit>
INFO: XNIO NIO Implementation Version 3.4.0.Final
Jan 11, 2017 11:07:46 PM org.jboss.remoting3.EndpointImpl <clinit>
INFO: JBoss Remoting version 4.0.21.Final
Jan 11, 2017 11:07:46 PM org.jboss.ejb.client.remoting.VersionReceiver handleMessage
INFO: EJBCLIENT000017: Received server version 2 and marshalling strategies [river]
Jan 11, 2017 11:07:46 PM org.jboss.ejb.client.remoting.RemotingConnectionEJBReceiver associate
INFO: EJBCLIENT000013: Successful version handshake completed for receiver context EJBReceiverContext{clientContext=org.jboss.ejb.client.EJBClientContext#29ca901e, receiver=Remoting connection EJB receiver [connection=org.jboss.ejb.client.remoting.ConnectionPool$PooledConnection#5649fd9b,channel=jboss.ejb,nodename=steves-mbp]} on channel Channel ID ecac0ca6 (outbound) of Remoting connection 6536e911 to /192.168.12.6:8080 of endpoint "config-based-ejb-client-endpoint" <520a3426>
Remote Foo bean returned hello
More information can be found in Remote EJB invocations via JNDI - EJB client API or remote-naming project.
More sample code can be found in the QuickStart repo at wildfly/quickstart/ejb-remote
PS. If you really want to set the distinct-name then you need to add a jboss-ejb3.xml file to your EJB jar containing:
<jboss:ejb-jar xmlns:jboss="http://www.jboss.com/xml/ns/javaee"
xmlns="http://www.jboss.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.jboss.com/xml/ns/javaee http://www.jboss.org/j2ee/schema/jboss-ejb3-2_0.xsd"
version="3.1"
impl-version="2.0">
<distinct-name>something-distinct</distinct-name>
</jboss:ejb-jar>
Dynamic EJB Client Properties
If you need to be able to provision the jboss-ejb-client.properties
dynamically then the simplest solution would be generate this file
on the fly, possibly at client initialisation time.
Set the jboss.ejb.client.properties.file.path system property to
point at a secure writable file system location. An insecure example might be something like
-Djboss.ejb.client.properties.file.path=/tmp/whizbang-ejb.properties
or
System.setProperty("jboss.ejb.client.properties.file.path", "/tmp/whizbang-ejb.properties");
Generate a properties file named
with the String defined by jboss.ejb.client.properties.file.path according to the format described for jboss-ejb-client.properties files.
Proceed with InitialContext creation
There are other alternatives that involve hacking the provided jboss-ejb-client
code. However you need to remember that this is LGPL code and you and your company
would need to make your hacks publicly available.

Before sharing what I learned I want to give a big shout-out to #Steve_C who went way beyond the call of duty in helping me, including a lengthy chat session. In case anyone wonders, he is not ME, by the way.
Meaning no disrespect to #Steve_C or his answer (which I have upvoted as useful), there is more to be said here, as I've learned from very painful experience.
Here are some things I have learned:
1) It is necessary to have a jboss-ejb-client.properties file.
2) This file can be located either on the classpath or specified in a location specified by the following System property, which I set just prior to invoking the InitialContext constructor:
System.setProperty("jboss.ejb.client.properties.file.path", "/path/to/properties/file");
return new InitialContext(prop);
3) This file must name the connections:
remote.connections=conn1,conn2
4) For each connection named in the above property, host and port entries must be stored in the properties file
remote.connection.conn1.host=10.0.0.1
remote.connection.conn1.port=8080
remote.connection.conn2.host=10.0.0.2
remote.connection.conn2.port=8080
5) For each connection named, there must also be some method of authentication specified, either
a)
remote.connection.conn1.username=user1
remote.connection.conn1.password=topSecret
remote.connection.conn2.username=user2
remote.connection.conn2.password=open_sesame
or b)
remote.connection.conn1.connect.options.org.xnio.Options.SASL_POLICY_NOANONYMOUS=false
remote.connection.conn2.connect.options.org.xnio.Options.SASL_POLICY_NOANONYMOUS=false
which literally indicates that anonymous no-password invocations are not disallowed. (Let's hear it for double negatives!) I suppose it would be theoretically possible to have one connection using a password and another allowing anonymous login but I can't imagine why. However this is done, it must be specified connection by connection. There is an incorrect example on the web that includes both
remote.connection.conn2.connect.options.org.xnio.Options.SASL_POLICY_NOANONYMOUS=false
and username/password properties for the connection. The net effect of this is that the credentials can be incorrect and you still get login. I tried this and found it to be the case.
6) In spite of appearances, the specifying of java.naming.provider.url is necessary. It would be nice if JBoss could figure this out from the connection host and port properties mentioned above, but it can't! There may or may not be a good reason for this, I simply do not know.
Annoyingly, this CANNOT be specified in the Properties file. This seems to be a bug in the JBoss client. Since ":" is equivalent to "=" in the Java properties file specification, it is impossible to store URLs there with the http-remote:// notation or any url with the colon slash slash. The colon must be escaped with a backslash but evidently the JBoss client code is not calling Properties.load() to resolve the escaping correctly, but rather attempting to read it line for line? So this one must be specified in the Properties passed to the InitialContext creation. I have tried both ways and found that specify it in code works, whereas specifying it in a properties file doesn't.
So we have the unfortunate situation that there are two methods of supplying data to the InitialContext, some by properties file and some in the initial environment Hashtable passed to the InitialContext constructor. Some things must be done in one place, and other things must be done in the other. And none of this is properly documented.

Related

#PutChild Upload file with milton webdav in Mac Finder failed

I'm using milton, and my upload code as follows:
#PutChild
#Transactional
public FileContentItem uploadFile(FolderContentItem parent, String name, byte[] bytes){
String traceId = UuidGenUtil.createUuid();
try {
QUERY_LOGGER.info("[uploadFile][NetdiskController],action=Request, name={}, size={},traceId={}",name,bytes.length,traceId);
In windows, i can upload file successfully, but with Mac Finder, the length of bytes is always 0, and the error as follow:
The Finder can't complete the operation because some data in "Shot.png" can't be read or written (Error code -36)
Anyone know why? Thanks
Update: I try ForkLift webdav client in mac and can upload file successfully
The problem is that mac finder sends first request for creating new file without any byte
After it - call LOCK, which is not available for Dav Level 1, that's why you have bad response from server and mac stop uploading a file. This method availiable only for Dav level 2, so you have to get enterprise license of milton to make it work
After Locking object Finder uploads the file
After - calls UNLOCK method
SO if you want to use mac finder for webdav in milton you have several options:
Get the trial enterprise license and look into this example:https://github.com/miltonio/milton2/tree/master/examples/milton-anno-ref
Realize these methods by yourself by webdav specs
Mock it - extend from MiltonFilter or look into MyOwnServlet in example and in method doFilter/service write something like this:
//mock method, do not use it in production!
HttpServletRequest request = (HttpServletRequest)req;
HttpServletResponse response = (HttpServletResponse) resp;
if(request.getMethod().equals("LOCK")){
response.setStatus(200);
response.addHeader("Lock-Token", "<opaquelocktoken:e71d4fae-5dec-22d6-fea5-00a0c91e6be4>");
} else if(request.getMethod().equals("UNLOCK")){
response.setStatus(204);
}else {
doMiltonProcessing((HttpServletRequest) req, (HttpServletResponse) resp);
}
I've checked this code working in the examble by link above: make in web.xml method serving by MyOwnServlet, disable authentication in init by implementing empty security manager, set controller packages to scan "com.mycompany"
p.s. to build the example project I've to delete milton client dependency from pom.xml file

ojdbc6 driver not in classpath when deployed via Wildfly 10 admin console?

We are using Wildfly 10 for the first time, upgrading from JBoss EAP 5.1.2. One thing that we need is to have our datasources using the ojdbc6 Oracle driver. I know there are 3 ways to configure them:
1 - Installing the driver and configuring the modules and datasources via configuration files, as shown in this article:
http://www.adam-bien.com/roller/abien/entry/installing_oracle_jdbc_driver_on
2 - Put the ojdbc6.jar in the D:\wildfly-10.1.0.Final\standalone\deployments folder, start the server. Via Wildfly 10 Administration Console, configure the datasource in Configuration -> Subsystems -> Datasources -> Non-XA usint the ojdbc6 driver we put in deployments folder;
3 - Via Wildfly 10 Administration Console, deploy the ojdbc6.jar like any normal deploy in Deployment tab, and them via Wildfly 10 Administration Console, configure the datasource in Configuration -> Subsystems -> Datasources -> Non-XA usint the ojdbc6 driver we just deployed.
Since our customers are used and demand instalations via administration consoles whenever possible, we choose way number 3 to configure the ojdbc6 driver and create our datasources.
Now here's the problem: our application has an environment check that among other things checks the Oracle driver version to make sure we are using the ojdbc6 Oracle driver. This environment check is mandatory for our application to start. Or environment check class has the following code to check the Oracle driver:
/**
* #return Caminho do jar do driver Oracle
* #see "http://www.javaxt.com/Tutorials/Jar/How_to_Get_the_Physical_Path_of_a_Jar_File"
*/
private String getOracleJarPath() {
try {
// Oracle driver class
final Class<?> clazz = oracle.jdbc.OracleDriver.class;
final String path = clazz.getPackage().getName().replace(".", "/");
String url = clazz.getClassLoader().getResource(path).toString();
url = url.replace(" ", "%20"); // Normalize URI
url = url.replace(path + "/", ""); // remove package from path
final URI uri = new URI(url);
return new File(uri.getPath()).getAbsolutePath();
} catch (final Exception e) {
// Nothing to do
}
return StringUtils.EMPTY;
}
When I deploy our application via Wildfly 10 Administration Console an error happens at line 38 (8 in the above code):
2017-06-21 10:54:49,332 ERROR [br.com.synchro.framework.ambiente.service.impl.ValidadorAmbienteServiceImpl] (default task-2) Erro ao validar ambiente em todos os estágios.: java.lang.NoClassDefFoundError: oracle/jdbc/OracleDriver
at br.com.synchro.sfw.infra.ambiente.integration.impl.ValidadorAmbienteVersaoDriverJdbc.getOracleJarPath(ValidadorAmbienteVersaoDriverJdbc.java:38)
at br.com.synchro.sfw.infra.ambiente.integration.impl.ValidadorAmbienteVersaoDriverJdbc.validarDriverOracle(ValidadorAmbienteVersaoDriverJdbc.java:149)
at br.com.synchro.sfw.infra.ambiente.integration.impl.ValidadorAmbienteVersaoDriverJdbc.validar(ValidadorAmbienteVersaoDriverJdbc.java:106)
at br.com.synchro.framework.ambiente.service.impl.ValidadorAmbienteServiceImpl.validarAmbienteSegundoEstagio(ValidadorAmbienteServiceImpl.java:137)
at br.com.synchro.framework.ambiente.service.impl.ValidadorAmbienteServiceImpl.validarAmbienteTodosEstagios(ValidadorAmbienteServiceImpl.java:156)
at br.com.synchro.framework.gui.presentation.filter.ValidacaoAmbienteFilter.doFilter(ValidacaoAmbienteFilter.java:55)
at io.undertow.servlet.core.ManagedFilter.doFilter(ManagedFilter.java:61)
at io.undertow.servlet.handlers.FilterHandler$FilterChainImpl.doFilter(FilterHandler.java:131)
at br.com.synchro.framework.gui.presentation.filter.AplicacaoPatchFilter.doFilter(AplicacaoPatchFilter.java:53)
at io.undertow.servlet.core.ManagedFilter.doFilter(ManagedFilter.java:61)
at io.undertow.servlet.handlers.FilterHandler$FilterChainImpl.doFilter(FilterHandler.java:131)
at br.com.synchro.framework.gui.presentation.filter.XUaCompatibleFilter.doFilter(XUaCompatibleFilter.java:28)
at io.undertow.servlet.core.ManagedFilter.doFilter(ManagedFilter.java:61)
at io.undertow.servlet.handlers.FilterHandler$FilterChainImpl.doFilter(FilterHandler.java:131)
...
Thus mean, we can't find the driver in our application classpath!
When I created the driver and datasource via method 1, our application works with no problem. But if I use method 2 or 3 the application cannot find the driver in the classpath at all. Since our customers demand instalation exclusively via Administration Console, what can I do or what am I doing wrong that the driver is not in our application classpath?!
Thanks in advance!!!
Try something like:
#Startup
#Singleton
public class JDBCDriverVerifier {
#Resource(name="java:jboss/datasources/YourDS)
private DataSource ds;
#PostConstruct
void checkDriver() {
try(Connection conn = ds.getConnection()) {
DatabaseMetaData metaData = conn.getMetaData();
String driverName = metaData.getDriverName();
String driverVersion = metaData.getDriverVersion();
// get other meta data if useful
// validate and throw exception if it fails...
}
}
}
You may need to experiment to see what metadata is the most useful for you.
Note that this will work even if you have a WAR only deployment.
Also, it's worth educating your customers about the value of using JBoss CLI scripts to configure their servers. These scripts can be source controlled (and commented), allowing new environments to be brought up quickly because they make the process repeatable. Console configuration is almost never repeatable. Most of the major Java EE server implementations have this capability in one form or another.

403 error in production from WindowsAzure.Storage

I have a WebForms app that uses the WindowsAzure.Storage API v3. It works fine in development and in one production environment, but I'm rolling out a new instance and any code that calls out Azure Blob Storage gives me a 403 error.
I've been fiddling with this for awhile, and it fails on any call out to Blob Storage, so rather than show my code I'll show my stack trace:
[WebException: The remote server returned an error: (403) Forbidden.]
System.Net.HttpWebRequest.GetResponse() +8525404
Microsoft.WindowsAzure.Storage.Core.Executor.Executor.ExecuteSync(RESTCommand`1 cmd, IRetryPolicy policy, OperationContext operationContext) +1541
[StorageException: The remote server returned an error: (403) Forbidden.]
Microsoft.WindowsAzure.Storage.Core.Executor.Executor.ExecuteSync(RESTCommand`1 cmd, IRetryPolicy policy, OperationContext operationContext) +2996
Microsoft.WindowsAzure.Storage.Blob.CloudBlobContainer.CreateIfNotExists(BlobContainerPublicAccessType accessType, BlobRequestOptions requestOptions, OperationContext operationContext) +177
ObsidianData.Azure.Storage.GetContainer(CloudBlobClient client, Containers targetContainer) in D:\Dev\nSource\Obsidian\Source\ObsidianData\Azure\Storage.vb:84
ObsidianWeb.Leads.HandleListenLink(String fileName, HyperLink link) in D:\Dev\nSource\Obsidian\Source\ObsidianWeb\Bdc\Leads.aspx.vb:188
ObsidianWeb.Leads.LoadEntity_ContactDetails(BoLead lead) in D:\Dev\nSource\Obsidian\Source\ObsidianWeb\Bdc\Leads.aspx.vb:147
ObsidianWeb.Leads.LoadEntity(BoLead Lead) in D:\Dev\nSource\Obsidian\Source\ObsidianWeb\Bdc\Leads.aspx.vb:62
EntityPages.EntityPage`1.LoadEntity() +91
EntityPages.EntityPage`1.Page_LoadComplete(Object sender, EventArgs e) +151
System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint) +4018
Here's what I've tried...
The AzureStorageConnectionString that fails in this environment definitely works in production
Other connection strings (from the other production environment, which works) also get a 403 here
There seemed to be an issue with timestamps in some old versions of the REST api (which I am not directly using...) so I made certain the times are correct, even tried switching the server to UTC time.
Tried toggling the connection string between http/https.
Upgraded to the latest version of the API (v3.1)
Tried fiddling with the code to ensure that every call out to Azure Storage gets 403. It does.
In desperation, Installed Azure Powershell on the server just to verify that some type of communication with Azure is working. And that worked fine.
Browsed to the azure management portal as well and that works fine.
Any ideas? This should just be using port 80 or 443, right? So there should be no way this is some kind of network issue. Let me know if that's wrong.
The working production machine is an Azure VM (Server 2008 R2 with IIS 7.5)
There are also some differences with the server:
This new machine is physical hardware (Server 2012 and IIS 8)
This IS using a different storage account inside my azure subscription, however I've tried a total of 3 connection strings and none of them work here.
UPDATE: someone asked to see the code. Okay, I wrote a class called Azure.Storage, which just abstracts my cloud storage code. We are failing on a call to Storage.Exists, so here's the part of that class that feels relevant:
Public Shared Function Exists(container As Containers, blobName As String) As Boolean
Dim Dir As CloudBlobContainer = GetContainer(container)
Dim Blob As CloudBlockBlob = Dir.GetBlockBlobReference(blobName.ToLower())
Return Blob.Exists()
End Function
Private Shared Function GetContainer(client As CloudBlobClient, targetContainer As Containers)
Dim Container As CloudBlobContainer = client.GetContainerReference(targetContainer.ToString.ToLower())
Container.CreateIfNotExists()
Container.SetPermissions(New BlobContainerPermissions() With {.PublicAccess = BlobContainerPublicAccessType.Blob})
Return Container
End Function
Private Shared Function GetCloudBlobClient() As CloudBlobClient
Dim Account As CloudStorageAccount = CloudStorageAccount.Parse(Settings.Cloud.AzureStorageConnectionString())
Return Account.CreateCloudBlobClient()
End Function
...Containers is just an enum of container names (there are several):
Public Enum Containers
CallerWavs
CampaignImports
Delve
Exports
CampaignImages
Logos
ReportLogos
WebLinkImages
End Enum
...Yes, they have upper-case characters, which causes problems. Everything is forced to lowercase before it goes out.
Also I did verify that the correct AzureConnectionString is coming out of my settings class. Again, I tried a few that work elsewhere. And this one works elsewhere also!
Please check the clock on the servers in question. Apart from the incorrect account key, you can also get 403 error if the time on the server is not in sync with the time on storage servers (Give or take +/- 15 minutes deviation is allowed).
I also ran into this error. My problem was that I had turned ON dynamic IP security restrictions in my web.config and the number of files being downloaded in some cases (e.g. with pages with lots of images) was exceeding the max thresholds I had defined in my web.config.
In my case Access key is not same as connection string using by the source code.
So try to recheck on your Azure -> [Storage Account Name] -> Access Keys -> key1 -> Key & Connection string.

Slick2D KryoNet Applet

I'm using Kryonet with Slick2d to make a java game.
It works fine when running as a java application, however when running as an applet I get the following error:
00:00 INFO: [kryonet] Server opened.
00:04 DEBUG: [kryonet] Port 9991/TCP connected to: /(ip):55801
00:04 DEBUG: [kryo] Write: RegisterTCP
00:04 INFO: [kryonet] Connection 1 connected: /(ip)
00:04 INFO: [SERVER] Someone has connected.
00:04 ERROR: [kryonet] Error reading TCP from connection: Connection 1
com.esotericsoftware.kryonet.KryoNetException: Error during deserialization.
at com.esotericsoftware.kryonet.TcpConnection.readObject(TcpConnection.java:141)
at com.esotericsoftware.kryonet.Server.update(Server.java:192)
at com.esotericsoftware.kryonet.Server.run(Server.java:350)
at java.lang.Thread.run(Unknown Source)
Caused by: com.esotericsoftware.kryo.KryoException: Buffer underflow.
at com.esotericsoftware.kryo.io.Input.require(Input.java:162)
at com.esotericsoftware.kryo.io.Input.readLong(Input.java:621)
at com.esotericsoftware.kryo.io.Input.readDouble(Input.java:745)
at com.esotericsoftware.kryo.serializers.DefaultSerializers$DoubleSerializer.read(DefaultSerializers.java:141)
at com.esotericsoftware.kryo.serializers.DefaultSerializers$DoubleSerializer.read(DefaultSerializers.java:131)
at com.esotericsoftware.kryo.Kryo.readClassAndObject(Kryo.java:735)
at com.esotericsoftware.kryonet.KryoSerialization.read(KryoSerialization.java:57)
at com.esotericsoftware.kryonet.TcpConnection.readObject(TcpConnection.java:139)
... 3 more
00:04 INFO: [SERVER] Someone has disconnected.
00:04 INFO: [kryonet] Connection 1 disconnected.
The server is running locally as a runnable jar and the client applet in a HTML file locally aswell, which is running xampp to act as a web server.
I've tried different serializers, buffer sizes and sending just single String/Booleans etc, it just doesn't seem to like anything.
The client connects to the server perfectly fine, however when it comes to sending any packets, I get the above error, no matter what packet is sent.
Any help/advice would be really appreciated - I've been stumped on this for a while!
Thanks
I believe I have the same problem or at least similar one. I am using Kryonet for server and client. The client is an applet and when I run it trough Eclipse's Applet Viewer it works fine. When I run it trough a web server I get similar errors. Client and server connect, server receives client's packets, but the client gives an error wherever it tries any deserialization. I found that the applet permissions are to blame. If you change the permissions of the Applet Viewer (if you are using Eclipse) to be the same as of a web page, you will get the same errors. The advantage is that you can then debug the problem.
To change the permissions for Eclipse:
Go to your project folder \bin\ and open "java.policy.applet". Inside you should have:
grant {
permission java.security.AllPermission;
};
Change that to:
grant {
permission java.io.FilePermission "<<ALL FILES>>", "read, write, execute, delete";
permission java.net.SocketPermission "*", "accept, connect, listen, resolve";
permission java.util.PropertyPermission "*", "read, write";
permission java.lang.RuntimePermission "*";
permission java.awt.AWTPermission "showWindowWithoutWarningBanner";
};
With this change I had the same behavior for Applet Viewer as with an embedded applet. This is not a full solution, but can help in finding the cause of the problem.
Update:
I have found what is the problem in my case. The problem is in the FieldSerializer and the other serializers using it. When a class is registered, the FieldSerializer goes over it's fields and set's them all to be accessible. This operation is not allowed for an applet. The result is wrong registration and serialization/deserialization. I have found 2 workarounds:
1) Use of another serializer. The default one is a FieldSerializer and can be changed using
public void setDefaultSerializer (Class<? extends Serializer> serializer)
another option is to set the serializer when registering each class. Do not use serializers based on the FieldSerializer.
2) Try to fix the FieldSerializer. What I am doing is not fully correct, but it works in my case. We will make the FieldSerializer continue the registration if setting of the accessibility is causing an Exception. Another thing we need to do is set all fields of the classes we register to public. TO change the FieldSerializer you need the Kryo sources. Go to FieldSerializer.java, mething rebuildCachedFields(). You will find the following code there:
if (!field.isAccessible()) {
if (!setFieldsAsAccessible) continue;
try {
field.setAccessible(true);
} catch (AccessControlException ex) {
continue;
}
}
You need to change that to:
if (!field.isAccessible()) {
if (setFieldsAsAccessible)
try {
field.setAccessible(true);
} catch (AccessControlException ex) {
}
}
The other thing that needs to be changed is all of the registered classes to have only public fields.
I have similar problem in gradle build. May be you need just increase memory (either heap or PermSize) for the applet JVM

Starting new process from ASP.NET fails

I'm trying to start a new process from my WCF Service. For that purpose I use
var process = Process.Start(
new ProcessStartInfo { WorkingDirectory = config.WorkingDirectory,
FileName = config.WorkingDirectory,
Arguments = string.Format("{0} {1}", mpcName, jobId),
CreateNoWindow = false,
WindowStyle = ProcessWindowStyle.Hidden });
The WebApp is using a separate AppDomain whose Identity is set to a user account having administrator rights on the server.
Process.Start throws an exception telling
Server execution failed, at System.Diagnostics.Process.StartWithShellExecuteEx(ProcessStartInfo startInfo)
I also tested setting user and password in ProcessStartInfo. Specifying the password was quite tricky (SecureString) and then I received
The stub received bad data, at System.Diagnostics.Process.StartWithCreateProcess(ProcessStartInfo startInfo)
so I skipped this way.
Do you know what is the reason for my problem and how I can fix it.
I forgot: I'm using Windows Server 2008 R2, IIS 7
I got it!
It's very strange but the only change needed was to invoke
Process.Start(exeFullPath, args);
Obviously the combination of ProcessStartInfo props is important.
This q/a helped me fix this issue in one of my projects, but different cause --
was trying to start process as a Domain user from an integration test being run by nCrunch. Turns out MY problem was a really long argument string.
(same argument string works with no user/password)
Environment is Windows 8, 64 bit.
Anyway, just gonna have to pass the arg data a different way.

Resources