• Post Reply Bookmark Topic Watch Topic
  • New Topic
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Campbell Ritchie
  • Paul Clapham
  • Ron McLeod
  • Bear Bibeault
  • Liutauras Vilda
Sheriffs:
  • Jeanne Boyarsky
  • Tim Cooke
  • Junilu Lacar
Saloon Keepers:
  • Tim Moores
  • Tim Holloway
  • Stephan van Hulst
  • Jj Roberts
  • Carey Brown
Bartenders:
  • salvin francis
  • Frits Walraven
  • Piet Souris

Servlet giving runtimeexception in Netbeans IDE 12 and Apache tomcat 9.0.41 in MacOS

 
Greenhorn
Posts: 8
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
a simple servlet:

web.xml:

but I get the following error:

12-Jan-2021 21:53:14.428 INFO [http-nio-8081-exec-11] org.apache.catalina.core.ApplicationContext.log Marking servlet [firstServlet] as unavailable
12-Jan-2021 21:53:14.428 SEVERE [http-nio-8081-exec-11] org.apache.catalina.core.StandardWrapperValve.invoke Allocate exception for servlet [firstServlet]
java.lang.RuntimeException:
at simple.servlets.FirstServlet.<init>(FirstServlet.java:1)
at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:64)
at java.base/jdk.internal.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
at java.base/java.lang.reflect.Constructor.newInstanceWithCaller(Constructor.java:500)
at java.base/java.lang.reflect.Constructor.newInstance(Constructor.java:481)
at org.apache.catalina.core.DefaultInstanceManager.newInstance(DefaultInstanceManager.java:151)
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:97)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:542)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:143)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92)
at org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:690)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:78)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:343)
at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:374)
at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:65)
at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:888)
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1597)
at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1130)
at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:630)
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
at java.base/java.lang.Thread.run(Thread.java:832)
12-Jan-2021 21:54:33.982 INFO [http-nio-8081-exec-26] org.apache.catalina.core.ApplicationContext.log Marking servlet [firstServlet] as unavailable
12-Jan-2021 21:54:33.983 SEVERE [http-nio-8081-exec-26] org.apache.catalina.core.StandardWrapperValve.invoke Allocate exception for servlet [firstServlet]
java.lang.RuntimeException:
at simple.servlets.FirstServlet.<init>(FirstServlet.java:1)
at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:64)
at java.base/jdk.internal.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
at java.base/java.lang.reflect.Constructor.newInstanceWithCaller(Constructor.java:500)
at java.base/java.lang.reflect.Constructor.newInstance(Constructor.java:481)
at org.apache.catalina.core.DefaultInstanceManager.newInstance(DefaultInstanceManager.java:151)
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:97)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:542)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:143)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92)
at org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:690)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:78)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:343)
at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:374)
at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:65)
at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:888)
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1597)
at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1130)
at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:630)
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
at java.base/java.lang.Thread.run(Thread.java:832)

servlet-api.jar is correctly mapped to CLASSPATH. Any help to resolve it would be appreciated.
 
Saloon Keeper
Posts: 12623
273
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Welcome to CodeRanch.

In your Catalina logs you can see that your servlet is being marked as unavailable. Maybe they give a reason for that in the log lines above it, but you haven't copied those lines here.
 
Rancher
Posts: 4786
50
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Is that the whole of the servlet code?
I notice the comment (presumably IDE one) about something that's been collapsed.

Just asking because this will occur if you've not got a no-args constructor available for your servlet.
 
Saloon Keeper
Posts: 6802
162
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Dave Tolls wrote:Just asking because this will occur if you've not got a no-args constructor available for your servlet.


I would go a bit further: a servlet should never have a constructor, period. Any required initializations should happen in the init(ServletConfig) method.

I would also point out that the service method should almost never be overridden. That's what the doGet and doPost methods  are for.
 
Saloon Keeper
Posts: 23041
157
Android Eclipse IDE Tomcat Server Redhat Java Linux
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Welcome to the Ranch! I have added Code tags to make the formatted text (java and XML) easier to read. The "Code" button on our message editor can do that for you.

Your stack trace does not seem to match the source code (which looks to have been copied out someone's example on basic servlets, but that's OK). It seems to be having a problem with initialization, either because the actual code has a constructor method in it or because there's a  member variable defined whose initialization expression failed. So if you have a more complete example, we'd like to see it. I see that Dave thinks you've collapsed the IDE display and if that's true, please expand it, since apparently the IDE is interfering with proper copy-and-paste.

CLASSPATH doesn't matter to Tomcat or NetBeans. They each have their own means of managing classpaths automatically. Tomcat, in fact, has multiple classpaths depending on what part of the system you're working with. It sets up a unique classpath foreach webapp, for example.
 
Bj Krishna
Greenhorn
Posts: 8
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hi Tim: this is the catalina logs: I doubted why it shows this warning and whether this could be a reason but couldnt figure it out. I have copied the ones that matches with the time stamp of stack trace.

12-Jan-2021 21:53:02.463 INFO [http-nio-8081-exec-15] org.apache.catalina.startup.HostConfig.undeploy Undeploying context [/webapp1]
12-Jan-2021 21:53:07.567 INFO [http-nio-8081-exec-16] org.apache.catalina.startup.HostConfig.deployDescriptor Deploying deployment descriptor [/Users/bobinkrishna/Java/apache-tomcat-9.0.41/conf/Catalina/localhost/webapp1.xml]
12-Jan-2021 21:53:07.567 WARNING [http-nio-8081-exec-16] org.apache.catalina.startup.HostConfig.deployDescriptor The path attribute with value [/webapp1] in deployment descriptor [/Users/bobinkrishna/Java/apache-tomcat-9.0.41/conf/Catalina/localhost/webapp1.xml] has been ignored
12-Jan-2021 21:53:07.591 INFO [http-nio-8081-exec-16] org.apache.catalina.startup.HostConfig.deployDescriptor Deployment of deployment descriptor [/Users/bobinkrishna/Java/apache-tomcat-9.0.41/conf/Catalina/localhost/webapp1.xml] has finished in [25] ms
12-Jan-2021 21:53:07.596 INFO [http-nio-8081-exec-19] org.apache.catalina.util.LifecycleBase.start The start() method was called on component [StandardEngine[Catalina].StandardHost[localhost].StandardContext[/webapp1]] after start() had already been called. The second call will be ignored.
12-Jan-2021 21:53:41.814 INFO [http-nio-8081-exec-19] org.apache.catalina.core.StandardContext.reload Reloading Context with name [/webapp1] has started
12-Jan-2021 21:53:41.836 INFO [http-nio-8081-exec-19] org.apache.catalina.core.StandardContext.reload Reloading Context with name [/webapp1] is completed
12-Jan-2021 21:53:51.229 INFO [http-nio-8081-exec-13] org.apache.catalina.core.StandardContext.reload Reloading Context with name [/webapp1] has started
12-Jan-2021 21:53:51.250 INFO [http-nio-8081-exec-13] org.apache.catalina.core.StandardContext.reload Reloading Context with name [/webapp1] is completed
12-Jan-2021 21:54:11.322 INFO [http-nio-8081-exec-19] org.apache.catalina.core.StandardContext.reload Reloading Context with name [/webapp1] has started
12-Jan-2021 21:54:11.336 INFO [http-nio-8081-exec-19] org.apache.catalina.core.StandardContext.reload Reloading Context with name [/webapp1] is completed
12-Jan-2021 21:54:25.636 INFO [http-nio-8081-exec-16] org.apache.catalina.startup.HostConfig.undeploy Undeploying context [/webapp1]
12-Jan-2021 21:54:29.897 INFO [http-nio-8081-exec-11] org.apache.catalina.startup.HostConfig.deployDescriptor Deploying deployment descriptor [/Users/bobinkrishna/Java/apache-tomcat-9.0.41/conf/Catalina/localhost/webapp1.xml]
12-Jan-2021 21:54:29.898 WARNING [http-nio-8081-exec-11] org.apache.catalina.startup.HostConfig.deployDescriptor The path attribute with value [/webapp1] in deployment descriptor [/Users/bobinkrishna/Java/apache-tomcat-9.0.41/conf/Catalina/localhost/webapp1.xml] has been ignored
12-Jan-2021 21:54:29.929 INFO [http-nio-8081-exec-11] org.apache.catalina.startup.HostConfig.deployDescriptor Deployment of deployment descriptor [/Users/bobinkrishna/Java/apache-tomcat-9.0.41/conf/Catalina/localhost/webapp1.xml] has finished in [32] ms
12-Jan-2021 21:54:29.938 INFO [http-nio-8081-exec-25] org.apache.catalina.util.LifecycleBase.start The start() method was called on component [StandardEngine[Catalina].StandardHost[localhost].StandardContext[/webapp1]] after start() had already been called. The second call will be ignored.

It is my own example Tim which worked separately when I run it out of IDE.  The IDE creates a HTTPServlet by default but it was giving this error, so what I did was I removed the HTTPservlet and used GenericServlet just to check if it works without any error but it still gives the same error.  I basically deleted the collapsed methods of HTTPServlet which is what Dave is asking for but that is not in the code any more. what I copied is what exists in Servlet.

Did I give you the information you are looking out for ? also as you mentioned where can I check for any member variable defined whose initialization expression failed? thank you for your help.
 
Tim Moores
Saloon Keeper
Posts: 6802
162
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
You didn't answer this, which is important information:

Dave Tolls wrote:Is that the whole of the servlet code?


If not, post the whole code.

The IDE creates a HTTPServlet by default but it was giving this error, so what I did was I removed the HTTPservlet and used GenericServlet


You should extend HttpServlet, and then override doGet and/or doPost. Don't override service.
 
Bj Krishna
Greenhorn
Posts: 8
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Given you the snapshot of the code in IDE in the attached image. Also as you can see a small rounded i in front of the service method line which shows that I am just implementing the service method and I am sure this as worked before in the same netbeans. Also have a doubt when my web applications loads it shows up the index.html page and then I include the URL-pattern in the URL to run the application, could this be a problem should I need to link it from the index.html. Thank you.

let me know if anything else needed.

Thanks,
Krishna
code-in-IDE.png
the complete servlet code in IDE
the complete servlet code in IDE
 
Bj Krishna
Greenhorn
Posts: 8
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Tim as you requested I created a HTTPServlet and attached the entire code and response from the browser.

 
Bj Krishna
Greenhorn
Posts: 8
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
snapshot of httpservlet:
 
Tim Holloway
Saloon Keeper
Posts: 23041
157
Android Eclipse IDE Tomcat Server Redhat Java Linux
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
OK. You CAN override the service() method, and I've done so, but it's not recommended.

On the other hand, you SHOULD be subclassing HttpServlet, not GenericServlet. It understands more about how HTTP works than GenericServlet does.

For example, the implementation of service() in HttpServlet does a test of the incoming request, and if it's a GET request, it invokes doGet(), if it's a POST, it invokes doPost() and so forth. If you override service(), then you lose that logic unless you manually re-create it.
 
Bj Krishna
Greenhorn
Posts: 8
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
HTTPServlet:
Screen-Shot-2021-01-13-at-1.10.34-PM.png
[Thumbnail for Screen-Shot-2021-01-13-at-1.10.34-PM.png]
Screen-Shot-2021-01-13-at-1.10.59-PM.png
[Thumbnail for Screen-Shot-2021-01-13-at-1.10.59-PM.png]
 
Bj Krishna
Greenhorn
Posts: 8
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
error response from browser:
Screen-Shot-2021-01-13-at-1.12.08-PM.png
[Thumbnail for Screen-Shot-2021-01-13-at-1.12.08-PM.png]
 
Tim Moores
Saloon Keeper
Posts: 6802
162
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
In the future, please do not post Screenshots of code or error messages - post them as text. Then they can be copied, quoted and searched - none of which is possible with images.
 
Bj Krishna
Greenhorn
Posts: 8
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
I deleted all projects and installed Netbeans 12 again and created a fresh web application:

Here is the code generated by NETbeans IDE, I didnt change anything but just ran below is the code:



web.xml file:



error from browser:

HTTP Status 500 – Internal Server Error

Type Exception Report

Message Error instantiating servlet class [com.bobin.SampleServ]

Description The server encountered an unexpected condition that prevented it from fulfilling the request.

Exception

javax.servlet.ServletException: Error instantiating servlet class [com.bobin.SampleServ]
org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:542)
org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92)
org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:690)
org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:343)
org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:374)
org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:65)
org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:888)
org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1597)
org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1130)
java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:630)
org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
java.base/java.lang.Thread.run(Thread.java:832)
Root Cause

java.lang.RuntimeException:
com.bobin.SampleServ.<init>(SampleServ.java:1)
java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:64)
java.base/jdk.internal.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
java.base/java.lang.reflect.Constructor.newInstanceWithCaller(Constructor.java:500)
java.base/java.lang.reflect.Constructor.newInstance(Constructor.java:481)
org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:542)
org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92)
org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:690)
org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:343)
org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:374)
org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:65)
org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:888)
org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1597)
org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1130)
java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:630)
org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
java.base/java.lang.Thread.run(Thread.java:832)

log file:

13-Jan-2021 16:24:03.961 INFO [http-nio-8081-exec-12] org.apache.catalina.core.ApplicationContext.log Marking servlet [SampleServ] as unavailable
13-Jan-2021 16:24:03.961 SEVERE [http-nio-8081-exec-12] org.apache.catalina.core.StandardWrapperValve.invoke Allocate exception for servlet [SampleServ]
java.lang.RuntimeException:
at com.bobin.SampleServ.<init>(SampleServ.java:1)
at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:64)
at java.base/jdk.internal.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
at java.base/java.lang.reflect.Constructor.newInstanceWithCaller(Constructor.java:500)
at java.base/java.lang.reflect.Constructor.newInstance(Constructor.java:481)
at org.apache.catalina.core.DefaultInstanceManager.newInstance(DefaultInstanceManager.java:151)
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:97)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:542)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:143)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92)
at org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:690)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:78)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:343)
at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:374)
at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:65)
at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:888)
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1597)
at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1130)
at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:630)
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
at java.base/java.lang.Thread.run(Thread.java:832)

 
We cannot change unless we survive, but we will not survive unless we change. Evolving tiny ad:
Building a Better World in your Backyard by Paul Wheaton and Shawn Klassen-Koop
https://coderanch.com/wiki/718759/books/Building-World-Backyard-Paul-Wheaton
reply
    Bookmark Topic Watch Topic
  • New Topic